Skip to content

feat(odin): Upload fetch_logs files to a data set as a new copy each run (EDG-1037) - #592

Draft
vikramlc-cognite wants to merge 1 commit into
EDG-1035-action-outcome-statusfrom
EDG-1037-fetch-logs-data-set
Draft

vikramlc-cognite wants to merge 1 commit into
EDG-1035-action-outcome-statusfrom
EDG-1037-fetch-logs-data-set

Conversation

@vikramlc-cognite

Copy link
Copy Markdown
Contributor

Summary

fetch_logs uploads log files into the extractor's data set (when one is set), keeps a new copy on every run, and ends completed_with_errors when nothing was uploaded.

Type of change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that changes existing behavior)
  • Refactor (no functional change)
  • Documentation update
  • Chore / tooling / CI

What changed

  • New hook Extractor.get_log_upload_data_set_id(); the default uses the config data set when the config derives from WithDataSetId, otherwise none. A marked TODO(data-domains) placeholder for the future integration data domains field (not implemented).
  • _log_upload_action.py: passes data_set_id to upload_bytes only when set; removes overwrite=True; external ID is now extractor-logs-<integration>-<date>-<action external id> (hashed if over 255 characters).
  • Nothing uploaded -> completed_with_errors with "No log files were uploaded (0 of N ...)"; partial uploads stay succeeded; invalid parameters stay failed.
  • Per-file status for a day with no log file is now missing (was skipped), to match the missing_files counter. Counter keys are unchanged.
  • ActionContext.set_result(..., completed_with_errors=...); tests (about 12 existing ones updated); CHANGELOG.

Why it changed

  • Uploaded log files had no data set, were silently overwritten by repeat runs, and an empty fetch reported succeeded.
  • Related issue: EDG-1037 (parent: EDG-1031)
  • Related docs / discussion: PM decisions (extractor's own data set, then none; new copy each run; nothing uploaded -> Completed with Errors). Stacked on EDG-1035. Needs Odin completed_with_errors (cognitedata/odin#324).

What to focus on during review

  • The external-ID scheme and its 255-character fallback.
  • The default data-set hook: it does one data_sets.retrieve for a configured data set; an exception fails the action.
  • The visible change of the per-file status string from skipped to missing.

Test evidence

  • tests/test_unstable/test_log_upload_action.py: 9 net new tests (data set passed/omitted, default hook, two runs -> different IDs without overwrite, ID length, partial succeeded, none uploaded completed_with_errors, invalid range failed, cancel wins)
  • uv run pytest tests/test_unstable: 309 passed; the same 1 failed + 48 environment errors as master
  • ruff, ruff format, mypy, pre-commit run --all-files pass
  • 22 tests fail with the three production files reverted

Risks and unknowns

  • Open product question: a partial result (some days uploaded, some missing) still ends succeeded.
  • Log files accumulate (nothing is cleaned up), by design of "new copy each time".
  • The File and DB extractors should override the hook with their own configured data set in their repos (follow-up).
  • Needs Odin Add status codes to time series queue #324 deployed first.

Rollout and rollback

Checklist

  • Self-reviewed the diff
  • Tests added or updated (or N/A with reason)
  • Docs updated (or N/A): module docstring, CHANGELOG
  • No secrets, credentials, or PII committed
  • Breaking changes called out above and communicated to affected teams: new external-ID format, skipped -> missing status string

@vikramlc-cognite
vikramlc-cognite requested a review from a team as a code owner October 26, 2026 09:24

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the built-in fetch_logs action to upload a new copy of log files on every invocation instead of overwriting them, utilizing unique, deterministic external IDs. It also introduces the Extractor.get_log_upload_data_set_id() hook to resolve the target data set for log uploads and adds a new completed_with_errors action status when no files are uploaded. The review feedback correctly identifies a potential bug in the external ID generation where a negative room value would slice the integration ID from the end rather than truncating it, and provides a robust fix using max(0, room).

Comment on lines +155 to +156
room = MAX_EXTERNAL_ID_LENGTH - len("extractor-logs--") - len(suffix)
return f"extractor-logs-{integration_external_id[:room]}-{suffix}"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

If room is negative (for example, if MAX_EXTERNAL_ID_LENGTH is configured to be smaller or if suffix is longer in future modifications), integration_external_id[:room] will slice from the end of the string instead of truncating it. This would keep almost the entire string and could cause the external ID to exceed the limit, leading to upload failures. Ensure room is non-negative by using max(0, room).

Suggested change
room = MAX_EXTERNAL_ID_LENGTH - len("extractor-logs--") - len(suffix)
return f"extractor-logs-{integration_external_id[:room]}-{suffix}"
room = max(0, MAX_EXTERNAL_ID_LENGTH - len("extractor-logs--") - len(suffix))
return f"extractor-logs-{integration_external_id[:room]}-{suffix}"

@vikramlc-cognite
vikramlc-cognite marked this pull request as draft October 26, 2026 10:23
@codecov

codecov Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 85.33%. Comparing base (370f43a) to head (6087f48).

Additional details and impacted files
@@                        Coverage Diff                         @@
##           EDG-1035-action-outcome-status     #592      +/-   ##
==================================================================
+ Coverage                           85.25%   85.33%   +0.08%     
==================================================================
  Files                                  46       46              
  Lines                                4882     4910      +28     
==================================================================
+ Hits                                 4162     4190      +28     
  Misses                                720      720              
Files with missing lines Coverage Δ
...extractorutils/unstable/core/_log_upload_action.py 99.33% <100.00%> (+0.06%) ⬆️
cognite/extractorutils/unstable/core/actions.py 100.00% <100.00%> (ø)
cognite/extractorutils/unstable/core/base.py 89.53% <100.00%> (+0.22%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

fetch_logs asks the extractor for a data set (Extractor.get_log_upload_data_set_id),
no longer overwrites earlier uploads, and ends as completed_with_errors when no
file was uploaded.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@vikramlc-cognite
vikramlc-cognite force-pushed the EDG-1037-fetch-logs-data-set branch from 509f746 to 6087f48 Compare November 2, 2026 12:00

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants