Skip to content

Conversation

@saig214
Copy link
Contributor

@saig214 saig214 commented Dec 9, 2025

Changelog

  • Adds CorrelationContextInterceptor to automatically propagate atlan-* headers and trace_id from workflows to activities for distributed tracing
  • Refactors log formatting to dynamically include trace_id for request correlation
  • Enables end-to-end observability by ensuring correlation identifiers flow through the entire workflow execution
  • Correlation context (atlan-* fields) are now automatically available in OpenTelemetry logs as attributes

Checklist

  • Additional tests added
  • All CI checks passed
  • Relevant documentation updated

Copyleft License Compliance

  • Have you used any code that is subject to a Copyleft license (e.g., GPL, AGPL, LGPL)?
  • If yes, have you modified the code in the context of this project? please share additional details.

Note

Adds a Temporal interceptor to carry atlan-* fields and trace_id from workflow args to activity headers, wires it into the worker, and surfaces these in logging/OTEL; includes state/utility updates and tests.

  • Interceptors (Temporal):
    • Add CorrelationContextInterceptor to extract atlan-* and trace_id from workflow args, inject as activity headers, and set activity-side context.
    • Register interceptor in worker interceptors list.
  • Activities:
    • activities/__init__.py:get_workflow_args now preserves atlan-* keys from workflow_config into workflow_args.
  • Observability/Logging:
    • Introduce observability/context.py with request_context and correlation_context ContextVars.
    • logger_adaptor: allow extra fields, include atlan-* extras, display trace_id in log format, and merge correlation context (trace_id + atlan-*) into log kwargs; minor cleanups.
    • observability/utils: WorkflowContext allows dynamic atlan-* fields and merges correlation context.
    • FastAPI middleware updated to import request_context from new module.
  • Events:
    • Minor cleanup in activity interceptor.
  • Tests:
    • Add comprehensive unit tests for correlation context interceptor behavior and logging integration.

Written by Cursor Bugbot for commit f105d0a. This will update automatically on new commits. Configure here.

@github-actions
Copy link

github-actions bot commented Dec 9, 2025

📜 Docstring Coverage Report

RESULT: PASSED (minimum: 30.0%, actual: 76.0%)

Detailed Coverage Report
======= Coverage for /home/runner/work/application-sdk/application-sdk/ ========
----------------------------------- Summary ------------------------------------
| Name                                                                              | Total | Miss | Cover | Cover% |
|-----------------------------------------------------------------------------------|-------|------|-------|--------|
| application_sdk/__init__.py                                                       |     1 |    0 |     1 |   100% |
| application_sdk/constants.py                                                      |     1 |    0 |     1 |   100% |
| application_sdk/version.py                                                        |     1 |    0 |     1 |   100% |
| application_sdk/worker.py                                                         |     4 |    0 |     4 |   100% |
| application_sdk/activities/__init__.py                                            |    10 |    0 |    10 |   100% |
| application_sdk/activities/lock_management.py                                     |     3 |    0 |     3 |   100% |
| application_sdk/activities/common/__init__.py                                     |     1 |    1 |     0 |     0% |
| application_sdk/activities/common/models.py                                       |     3 |    1 |     2 |    67% |
| application_sdk/activities/common/utils.py                                        |     9 |    1 |     8 |    89% |
| application_sdk/activities/metadata_extraction/__init__.py                        |     1 |    1 |     0 |     0% |
| application_sdk/activities/metadata_extraction/base.py                            |     5 |    1 |     4 |    80% |
| application_sdk/activities/metadata_extraction/rest.py                            |     1 |    1 |     0 |     0% |
| application_sdk/activities/metadata_extraction/sql.py                             |    25 |    5 |    20 |    80% |
| application_sdk/activities/query_extraction/__init__.py                           |     1 |    1 |     0 |     0% |
| application_sdk/activities/query_extraction/sql.py                                |    13 |    1 |    12 |    92% |
| application_sdk/application/__init__.py                                           |    10 |    3 |     7 |    70% |
| application_sdk/application/metadata_extraction/sql.py                            |     7 |    1 |     6 |    86% |
| application_sdk/clients/__init__.py                                               |     4 |    0 |     4 |   100% |
| application_sdk/clients/atlan.py                                                  |     5 |    3 |     2 |    40% |
| application_sdk/clients/atlan_auth.py                                             |    10 |    0 |    10 |   100% |
| application_sdk/clients/base.py                                                   |     6 |    1 |     5 |    83% |
| application_sdk/clients/models.py                                                 |     3 |    0 |     3 |   100% |
| application_sdk/clients/redis.py                                                  |    27 |    0 |    27 |   100% |
| application_sdk/clients/sql.py                                                    |    16 |    0 |    16 |   100% |
| application_sdk/clients/temporal.py                                               |    14 |    1 |    13 |    93% |
| application_sdk/clients/utils.py                                                  |     2 |    1 |     1 |    50% |
| application_sdk/clients/workflow.py                                               |     9 |    2 |     7 |    78% |
| application_sdk/common/__init__.py                                                |     1 |    1 |     0 |     0% |
| application_sdk/common/aws_utils.py                                               |    10 |    1 |     9 |    90% |
| application_sdk/common/dapr_utils.py                                              |     2 |    1 |     1 |    50% |
| application_sdk/common/dataframe_utils.py                                         |     2 |    1 |     1 |    50% |
| application_sdk/common/error_codes.py                                             |    14 |    2 |    12 |    86% |
| application_sdk/common/file_converter.py                                          |     9 |    5 |     4 |    44% |
| application_sdk/common/utils.py                                                   |    16 |    2 |    14 |    88% |
| application_sdk/decorators/__init__.py                                            |     1 |    1 |     0 |     0% |
| application_sdk/decorators/locks.py                                               |     3 |    2 |     1 |    33% |
| application_sdk/decorators/mcp_tool.py                                            |     3 |    1 |     2 |    67% |
| application_sdk/docgen/__init__.py                                                |     5 |    2 |     3 |    60% |
| application_sdk/docgen/exporters/__init__.py                                      |     1 |    1 |     0 |     0% |
| application_sdk/docgen/exporters/mkdocs.py                                        |     7 |    3 |     4 |    57% |
| application_sdk/docgen/models/__init__.py                                         |     1 |    1 |     0 |     0% |
| application_sdk/docgen/models/export/__init__.py                                  |     1 |    1 |     0 |     0% |
| application_sdk/docgen/models/export/page.py                                      |     2 |    1 |     1 |    50% |
| application_sdk/docgen/models/manifest/__init__.py                                |     2 |    1 |     1 |    50% |
| application_sdk/docgen/models/manifest/customer.py                                |     3 |    1 |     2 |    67% |
| application_sdk/docgen/models/manifest/internal.py                                |     2 |    1 |     1 |    50% |
| application_sdk/docgen/models/manifest/metadata.py                                |     2 |    1 |     1 |    50% |
| application_sdk/docgen/models/manifest/page.py                                    |     2 |    1 |     1 |    50% |
| application_sdk/docgen/models/manifest/section.py                                 |     2 |    1 |     1 |    50% |
| application_sdk/docgen/parsers/__init__.py                                        |     1 |    1 |     0 |     0% |
| application_sdk/docgen/parsers/directory.py                                       |    13 |    2 |    11 |    85% |
| application_sdk/docgen/parsers/manifest.py                                        |     6 |    1 |     5 |    83% |
| application_sdk/events/__init__.py                                                |     1 |    0 |     1 |   100% |
| application_sdk/events/models.py                                                  |    13 |    1 |    12 |    92% |
| application_sdk/handlers/__init__.py                                              |     7 |    1 |     6 |    86% |
| application_sdk/handlers/base.py                                                  |     7 |    1 |     6 |    86% |
| application_sdk/handlers/sql.py                                                   |    19 |    6 |    13 |    68% |
| application_sdk/inputs/__init__.py                                                |     7 |    1 |     6 |    86% |
| application_sdk/inputs/iceberg.py                                                 |     7 |    3 |     4 |    57% |
| application_sdk/inputs/json.py                                                    |     7 |    1 |     6 |    86% |
| application_sdk/inputs/parquet.py                                                 |     7 |    1 |     6 |    86% |
| application_sdk/inputs/sql_query.py                                               |    11 |    1 |    10 |    91% |
| application_sdk/interceptors/__init__.py                                          |     1 |    1 |     0 |     0% |
| application_sdk/interceptors/cleanup.py                                           |     7 |    1 |     6 |    86% |
| application_sdk/interceptors/correlation_context.py                               |    13 |    0 |    13 |   100% |
| application_sdk/interceptors/events.py                                            |     9 |    1 |     8 |    89% |
| application_sdk/interceptors/lock.py                                              |    10 |    2 |     8 |    80% |
| application_sdk/observability/__init__.py                                         |     1 |    1 |     0 |     0% |
| application_sdk/observability/context.py                                          |     1 |    0 |     1 |   100% |
| application_sdk/observability/logger_adaptor.py                                   |    30 |    2 |    28 |    93% |
| application_sdk/observability/metrics_adaptor.py                                  |    16 |    2 |    14 |    88% |
| application_sdk/observability/observability.py                                    |    24 |    1 |    23 |    96% |
| application_sdk/observability/traces_adaptor.py                                   |    16 |    1 |    15 |    94% |
| application_sdk/observability/utils.py                                            |     4 |    1 |     3 |    75% |
| application_sdk/observability/decorators/observability_decorator.py               |     7 |    4 |     3 |    43% |
| application_sdk/outputs/__init__.py                                               |    14 |    0 |    14 |   100% |
| application_sdk/outputs/iceberg.py                                                |     5 |    1 |     4 |    80% |
| application_sdk/outputs/json.py                                                   |     8 |    1 |     7 |    88% |
| application_sdk/outputs/parquet.py                                                |    15 |    1 |    14 |    93% |
| application_sdk/server/__init__.py                                                |     4 |    0 |     4 |   100% |
| application_sdk/server/fastapi/__init__.py                                        |    24 |    5 |    19 |    79% |
| application_sdk/server/fastapi/models.py                                          |    27 |   27 |     0 |     0% |
| application_sdk/server/fastapi/utils.py                                           |     2 |    0 |     2 |   100% |
| application_sdk/server/fastapi/middleware/logmiddleware.py                        |     4 |    4 |     0 |     0% |
| application_sdk/server/fastapi/middleware/metrics.py                              |     3 |    3 |     0 |     0% |
| application_sdk/server/fastapi/routers/__init__.py                                |     1 |    1 |     0 |     0% |
| application_sdk/server/fastapi/routers/server.py                                  |     8 |    2 |     6 |    75% |
| application_sdk/server/mcp/__init__.py                                            |     1 |    1 |     0 |     0% |
| application_sdk/server/mcp/models.py                                              |     2 |    2 |     0 |     0% |
| application_sdk/server/mcp/server.py                                              |     5 |    0 |     5 |   100% |
| application_sdk/services/__init__.py                                              |     1 |    0 |     1 |   100% |
| application_sdk/services/atlan_storage.py                                         |     5 |    0 |     5 |   100% |
| application_sdk/services/eventstore.py                                            |     4 |    0 |     4 |   100% |
| application_sdk/services/objectstore.py                                           |    15 |    0 |    15 |   100% |
| application_sdk/services/secretstore.py                                           |    14 |    0 |    14 |   100% |
| application_sdk/services/statestore.py                                            |     8 |    1 |     7 |    88% |
| application_sdk/test_utils/__init__.py                                            |     1 |    1 |     0 |     0% |
| application_sdk/test_utils/workflow_monitoring.py                                 |     3 |    0 |     3 |   100% |
| application_sdk/test_utils/e2e/__init__.py                                        |    14 |    2 |    12 |    86% |
| application_sdk/test_utils/e2e/base.py                                            |    16 |    2 |    14 |    88% |
| application_sdk/test_utils/e2e/client.py                                          |    10 |    2 |     8 |    80% |
| application_sdk/test_utils/e2e/conftest.py                                        |     1 |    1 |     0 |     0% |
| application_sdk/test_utils/e2e/utils.py                                           |     3 |    1 |     2 |    67% |
| application_sdk/test_utils/hypothesis/__init__.py                                 |     1 |    1 |     0 |     0% |
| application_sdk/test_utils/hypothesis/strategies/__init__.py                      |     1 |    1 |     0 |     0% |
| application_sdk/test_utils/hypothesis/strategies/sql_client.py                    |     1 |    1 |     0 |     0% |
| application_sdk/test_utils/hypothesis/strategies/temporal.py                      |     6 |    1 |     5 |    83% |
| application_sdk/test_utils/hypothesis/strategies/clients/__init__.py              |     1 |    1 |     0 |     0% |
| application_sdk/test_utils/hypothesis/strategies/clients/sql.py                   |     1 |    1 |     0 |     0% |
| application_sdk/test_utils/hypothesis/strategies/common/__init__.py               |     1 |    1 |     0 |     0% |
| application_sdk/test_utils/hypothesis/strategies/common/logger.py                 |     3 |    0 |     3 |   100% |
| application_sdk/test_utils/hypothesis/strategies/handlers/__init__.py             |     1 |    1 |     0 |     0% |
| application_sdk/test_utils/hypothesis/strategies/handlers/sql/__init__.py         |     1 |    1 |     0 |     0% |
| application_sdk/test_utils/hypothesis/strategies/handlers/sql/sql_metadata.py     |     1 |    1 |     0 |     0% |
| application_sdk/test_utils/hypothesis/strategies/handlers/sql/sql_preflight.py    |     1 |    1 |     0 |     0% |
| application_sdk/test_utils/hypothesis/strategies/inputs/__init__.py               |     1 |    1 |     0 |     0% |
| application_sdk/test_utils/hypothesis/strategies/inputs/json_input.py             |     1 |    1 |     0 |     0% |
| application_sdk/test_utils/hypothesis/strategies/inputs/parquet_input.py          |     1 |    1 |     0 |     0% |
| application_sdk/test_utils/hypothesis/strategies/outputs/__init__.py              |     1 |    1 |     0 |     0% |
| application_sdk/test_utils/hypothesis/strategies/outputs/json_output.py           |     2 |    1 |     1 |    50% |
| application_sdk/test_utils/hypothesis/strategies/outputs/statestore.py            |     3 |    1 |     2 |    67% |
| application_sdk/test_utils/hypothesis/strategies/server/__init__.py               |     1 |    1 |     0 |     0% |
| application_sdk/test_utils/hypothesis/strategies/server/fastapi/__init__.py       |     1 |    1 |     0 |     0% |
| application_sdk/test_utils/scale_data_generator/__init__.py                       |     1 |    1 |     0 |     0% |
| application_sdk/test_utils/scale_data_generator/config_loader.py                  |    10 |    4 |     6 |    60% |
| application_sdk/test_utils/scale_data_generator/data_generator.py                 |    10 |    3 |     7 |    70% |
| application_sdk/test_utils/scale_data_generator/driver.py                         |     3 |    3 |     0 |     0% |
| application_sdk/test_utils/scale_data_generator/output_handler/__init__.py        |     1 |    1 |     0 |     0% |
| application_sdk/test_utils/scale_data_generator/output_handler/base.py            |     7 |    3 |     4 |    57% |
| application_sdk/test_utils/scale_data_generator/output_handler/csv_handler.py     |     5 |    5 |     0 |     0% |
| application_sdk/test_utils/scale_data_generator/output_handler/json_handler.py    |     5 |    5 |     0 |     0% |
| application_sdk/test_utils/scale_data_generator/output_handler/parquet_handler.py |     6 |    6 |     0 |     0% |
| application_sdk/transformers/__init__.py                                          |     3 |    1 |     2 |    67% |
| application_sdk/transformers/atlas/__init__.py                                    |     6 |    1 |     5 |    83% |
| application_sdk/transformers/atlas/sql.py                                         |    25 |    4 |    21 |    84% |
| application_sdk/transformers/common/__init__.py                                   |     1 |    1 |     0 |     0% |
| application_sdk/transformers/common/utils.py                                      |     6 |    0 |     6 |   100% |
| application_sdk/transformers/query/__init__.py                                    |    11 |    2 |     9 |    82% |
| application_sdk/workflows/__init__.py                                             |     4 |    0 |     4 |   100% |
| application_sdk/workflows/metadata_extraction/__init__.py                         |     2 |    2 |     0 |     0% |
| application_sdk/workflows/metadata_extraction/sql.py                              |     8 |    0 |     8 |   100% |
| application_sdk/workflows/query_extraction/__init__.py                            |     2 |    2 |     0 |     0% |
| application_sdk/workflows/query_extraction/sql.py                                 |     4 |    0 |     4 |   100% |
| examples/application_custom_fastapi.py                                            |    14 |   14 |     0 |     0% |
| examples/application_fastapi.py                                                   |     9 |    9 |     0 |     0% |
| examples/application_hello_world.py                                               |     7 |    7 |     0 |     0% |
| examples/application_sql.py                                                       |     5 |    4 |     1 |    20% |
| examples/application_sql_miner.py                                                 |     5 |    4 |     1 |    20% |
| examples/application_sql_with_custom_pyatlan_transformer.py                       |    11 |    9 |     2 |    18% |
| examples/application_sql_with_custom_transformer.py                               |     9 |    8 |     1 |    11% |
| examples/run_examples.py                                                          |     2 |    1 |     1 |    50% |
| tests/__init__.py                                                                 |     1 |    1 |     0 |     0% |
| tests/conftest.py                                                                 |     4 |    0 |     4 |   100% |
| tests/unit/__init__.py                                                            |     1 |    1 |     0 |     0% |
| tests/unit/test_worker.py                                                         |    10 |    5 |     5 |    50% |
| tests/unit/activities/__init__.py                                                 |     1 |    1 |     0 |     0% |
| tests/unit/activities/test_activities.py                                          |    41 |    3 |    38 |    93% |
| tests/unit/activities/test_lock_management.py                                     |    12 |    0 |    12 |   100% |
| tests/unit/activities/common/__init__.py                                          |     1 |    1 |     0 |     0% |
| tests/unit/activities/common/test_utils.py                                        |    28 |   10 |    18 |    64% |
| tests/unit/activities/metadata_extraction/__init__.py                             |     1 |    1 |     0 |     0% |
| tests/unit/activities/metadata_extraction/test_sql.py                             |    56 |   36 |    20 |    36% |
| tests/unit/activities/query_extraction/__init__.py                                |     1 |    1 |     0 |     0% |
| tests/unit/application/__init__.py                                                |     1 |    1 |     0 |     0% |
| tests/unit/application/test_application.py                                        |    36 |    3 |    33 |    92% |
| tests/unit/application/metadata_extraction/test_sql.py                            |    30 |    6 |    24 |    80% |
| tests/unit/clients/__init__.py                                                    |     1 |    1 |     0 |     0% |
| tests/unit/clients/test_async_sql_client.py                                       |    15 |   14 |     1 |     7% |
| tests/unit/clients/test_atlan_auth.py                                             |    11 |    0 |    11 |   100% |
| tests/unit/clients/test_atlan_client.py                                           |     7 |    7 |     0 |     0% |
| tests/unit/clients/test_atlanauth.py                                              |    11 |    1 |    10 |    91% |
| tests/unit/clients/test_base_client.py                                            |    23 |    1 |    22 |    96% |
| tests/unit/clients/test_redis_client.py                                           |    40 |    0 |    40 |   100% |
| tests/unit/clients/test_sql_client.py                                             |    28 |    6 |    22 |    79% |
| tests/unit/clients/test_temporal_client.py                                        |    20 |    4 |    16 |    80% |
| tests/unit/common/test_aws_utils.py                                               |    30 |    1 |    29 |    97% |
| tests/unit/common/test_credential_utils.py                                        |    30 |    1 |    29 |    97% |
| tests/unit/common/test_file_converter.py                                          |    29 |    0 |    29 |   100% |
| tests/unit/common/test_utils.py                                                   |    74 |    6 |    68 |    92% |
| tests/unit/common/test_utils_file_discovery.py                                    |    11 |    0 |    11 |   100% |
| tests/unit/decorators/__init__.py                                                 |     1 |    1 |     0 |     0% |
| tests/unit/decorators/test_mcp_tool.py                                            |    56 |    4 |    52 |    93% |
| tests/unit/docgen/parsers/test_directory_parser.py                                |    14 |    3 |    11 |    79% |
| tests/unit/docgen/parsers/test_manifest_parser.py                                 |    12 |   12 |     0 |     0% |
| tests/unit/handlers/__init__.py                                                   |     1 |    1 |     0 |     0% |
| tests/unit/handlers/test_base_handler.py                                          |    26 |    2 |    24 |    92% |
| tests/unit/handlers/sql/test_auth.py                                              |    10 |    4 |     6 |    60% |
| tests/unit/handlers/sql/test_check_schemas_and_databases.py                       |    14 |    4 |    10 |    71% |
| tests/unit/handlers/sql/test_extract_allowed_schemas.py                           |    11 |    3 |     8 |    73% |
| tests/unit/handlers/sql/test_metadata.py                                          |    27 |   10 |    17 |    63% |
| tests/unit/handlers/sql/test_preflight_check.py                                   |    16 |   15 |     1 |     6% |
| tests/unit/handlers/sql/test_prepare_metadata.py                                  |    14 |    4 |    10 |    71% |
| tests/unit/handlers/sql/test_tables_check.py                                      |     9 |    6 |     3 |    33% |
| tests/unit/handlers/sql/test_validate_filters.py                                  |    12 |    4 |     8 |    67% |
| tests/unit/inputs/test_base_input.py                                              |    33 |    4 |    29 |    88% |
| tests/unit/inputs/test_json.py                                                    |    23 |   12 |    11 |    48% |
| tests/unit/inputs/test_parquet.py                                                 |    45 |   31 |    14 |    31% |
| tests/unit/interceptors/__init__.py                                               |     1 |    1 |     0 |     0% |
| tests/unit/interceptors/test_correlation_context.py                               |    37 |    0 |    37 |   100% |
| tests/unit/observability/__init__.py                                              |     1 |    1 |     0 |     0% |
| tests/unit/observability/test_logger_adaptor.py                                   |    35 |    2 |    33 |    94% |
| tests/unit/observability/test_metrics_adaptor.py                                  |    14 |    1 |    13 |    93% |
| tests/unit/observability/test_traces_adaptor.py                                   |    10 |    1 |     9 |    90% |
| tests/unit/outputs/test_iceberg.py                                                |    11 |    4 |     7 |    64% |
| tests/unit/outputs/test_json_output.py                                            |     7 |    6 |     1 |    14% |
| tests/unit/outputs/test_output.py                                                 |    19 |    6 |    13 |    68% |
| tests/unit/outputs/test_parquet_output.py                                         |    57 |   10 |    47 |    82% |
| tests/unit/server/__init__.py                                                     |     1 |    1 |     0 |     0% |
| tests/unit/server/fastapi/test_fastapi.py                                         |     8 |    3 |     5 |    62% |
| tests/unit/server/fastapi/routers/__init__.py                                     |     1 |    1 |     0 |     0% |
| tests/unit/server/fastapi/routers/server.py                                       |     1 |    1 |     0 |     0% |
| tests/unit/server/mcp/__init__.py                                                 |     1 |    1 |     0 |     0% |
| tests/unit/server/mcp/test_mcp_server.py                                          |    24 |    1 |    23 |    96% |
| tests/unit/services/test_atlan_storage.py                                         |    10 |    0 |    10 |   100% |
| tests/unit/services/test_eventstore.py                                            |    18 |    0 |    18 |   100% |
| tests/unit/services/test_objectstore.py                                           |    26 |    5 |    21 |    81% |
| tests/unit/services/test_statestore.py                                            |    14 |    0 |    14 |   100% |
| tests/unit/transformers/__init__.py                                               |     1 |    1 |     0 |     0% |
| tests/unit/transformers/atlas/__init__.py                                         |     1 |    1 |     0 |     0% |
| tests/unit/transformers/atlas/test_column.py                                      |    17 |    6 |    11 |    65% |
| tests/unit/transformers/atlas/test_database.py                                    |     8 |    6 |     2 |    25% |
| tests/unit/transformers/atlas/test_function.py                                    |     9 |    5 |     4 |    44% |
| tests/unit/transformers/atlas/test_procedure.py                                   |     7 |    6 |     1 |    14% |
| tests/unit/transformers/atlas/test_schema.py                                      |     8 |    6 |     2 |    25% |
| tests/unit/transformers/atlas/test_table.py                                       |    13 |    6 |     7 |    54% |
| tests/unit/transformers/query/test_sql_transformer.py                             |    14 |    4 |    10 |    71% |
| tests/unit/transformers/query/test_sql_transformer_output_validation.py           |     5 |    2 |     3 |    60% |
| tests/unit/workflows/metadata_extraction/test_sql_workflow.py                     |     9 |    4 |     5 |    56% |
| tests/unit/workflows/query_extraction/__init__.py                                 |     1 |    1 |     0 |     0% |
| tests/unit/workflows/query_extraction/test_sql.py                                 |     8 |    3 |     5 |    62% |
|-----------------------------------------------------------------------------------|-------|------|-------|--------|
| TOTAL                                                                             |  2233 |  599 |  1634 |  73.2% |
---------------- RESULT: PASSED (minimum: 30.0%, actual: 73.2%) ----------------

@saig214 saig214 changed the title Lh 88 feat: Add Argo Attributes to Temporal Runs Dec 9, 2025
@github-actions
Copy link

github-actions bot commented Dec 9, 2025

🛠 Docs available at: https://k.atlan.dev/application-sdk/LH-88

@atlan-ci
Copy link
Collaborator

atlan-ci commented Dec 9, 2025

☂️ Python Coverage

current status: ✅

Overall Coverage

Lines Covered Coverage Threshold Status
6653 4804 72% 0% 🟢

New Files

No new covered files...

Modified Files

No covered modified files...

updated for commit: f105d0a by action🐍

@github-actions
Copy link

github-actions bot commented Dec 9, 2025

🛠 Full Test Coverage Report: https://k.atlan.dev/coverage/application-sdk/pr/880

@github-actions
Copy link

github-actions bot commented Dec 9, 2025

📦 Trivy Vulnerability Scan Results

Schema Version Created At Artifact Type
2 2025-12-12T18:39:05.656063565Z . filesystem

Report Summary

Target Type Vulnerabilities . filesystem ✅ None found

Scan Result Details

✅ No vulnerabilities found during the scan for ..

@github-actions
Copy link

github-actions bot commented Dec 9, 2025

📦 Trivy Secret Scan Results

Schema Version Created At Artifact Type
2 2025-12-12T18:39:13.313787934Z . filesystem

Report Summary

Target Type Secrets . filesystem ✅ None found

Scan Result Details

✅ No secrets found during the scan for ..

workflow_args["workflow_run_id"] = get_workflow_run_id()

# Preserve argo workflow metadata from workflow_config for logging context
workflow_args["argo_workflow_name"] = workflow_config.get(
Copy link

@vishnub-atlan vishnub-atlan Dec 10, 2025

Choose a reason for hiding this comment

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

we have two types of workflows
1/ cross-over 2.0 = inter-app orchestration (argo) and intra-app orchestration (temporal)
2/ cross-over 1.0 = inter-app orchestration (argo) and intra-app orchestration (argo).
3/ native = inter-app orchestration (mostly temporal) and intra-app orchestration (argo)

Essentially we have two kind of workflows then
1/ inter-app
2/ intra-app

Why not standardise the nomenclature across cross-overs and native so that we do not have to redo with tooling changes. Ideally these names should already be sorted out from product perspective but they aren't. Let this nomenclature be finalised between @anbarasantr and me

Copy link
Contributor Author

@saig214 saig214 Dec 10, 2025

Choose a reason for hiding this comment

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

Will be passing atlan-argo-workflow-id and atlan-argo-workflow-node as input args. In the sdk, we will pickup whichever has atlan-* and propogate the same to logs/otel.

Choose a reason for hiding this comment

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

please avoid having any argo references in SDK itself

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry typo, I meant atlan-*, we won't have argo references.

if LOG_LEVEL == "DEBUG":
colorize = True
format_str = atlan_format_str_color
colorize = LOG_LEVEL == "DEBUG"

Choose a reason for hiding this comment

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

I wish I had more details but I heard recently there was an issue due to attempt to color logs? I think Nishchith knows more details here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

escape sequences are added to give colour for terminal outputs, this is now behind a flag. I've refactored the same to use a method instead of a string.
If DEBUG flag is enabled, it will show coloured text ( appends some escape chars ), else it's normal text.

workflow_args["workflow_run_id"] = get_workflow_run_id()

# Preserve argo workflow metadata from workflow_config for logging context
workflow_args["argo_workflow_name"] = workflow_config.get(

Choose a reason for hiding this comment

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

it shouldn't matter to intra-app workflow if invocation is via argo or temporal inter-app workflow or via an API. Can you help me understand what is the log template that we plan to render using these details

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sample log
2025-12-10 15:24:18 [INFO] application_sdk.interceptors.cleanup atlan-argo-workflow-id=redshift-sai-test-12345 atlan-argo-workflow-node=redshift-sai-test-12345.run(0).extrat(2) - Cleanup completed successfully Workflow Context: Workflow ID: 617170a2-5c89-4c59-b212-03cf10d3d670 Run ID: 019b07a9-c0b4-7d2b-bbbf-01ac5b3a0ea7 Type: RedshiftMetadataExtractionWorkflow

Moved `request_context` and `correlation_context` ContextVar definitions
to a new dedicated module to resolve circular import dependencies between
`logger_adaptor.py` and `utils.py`.

Changes:
- Add `application_sdk/observability/context.py` with shared ContextVars
- Update `logger_adaptor.py` to import from context.py (re-exports for
  backward compatibility)
- Replace lazy imports with top-level imports in:
  - `utils.py`
  - `workflows/__init__.py`
  - `interceptors/events.py`
  - `logmiddleware.py`

Benefits:
- Cleaner dependency graph with explicit imports
- No more hidden lazy imports inside functions
- Backward compatible - existing imports from logger_adaptor still work
- Better code discoverability and maintainability
Modified the way correlation strings are constructed and accessed in the AtlanLoggerAdapter. The correlation string is now directly assigned to the record's extra dictionary, improving clarity and maintainability of the logging format.
vishnub-atlan
vishnub-atlan previously approved these changes Dec 10, 2025
saig214 and others added 9 commits December 11, 2025 21:22
…nhance logging format

- Changed `request_context` and `correlation_context` to allow None as default values.
- Added `trace_id` field to `LogExtraModel` for improved logging.
- Updated log formatting to include `trace_id` when present, while ensuring atlan-* headers are excluded from the display.
- Enhanced tests to verify trace_id extraction and logging behavior.
Signed-off-by: saig214 <[email protected]>
@saig214 saig214 changed the title feat: Add Argo Attributes to Temporal Runs feat: Add Atlan Attributes to Temporal Runs Dec 12, 2025
@AtMrun AtMrun merged commit 8a85a24 into main Dec 12, 2025
21 of 22 checks passed
@AtMrun AtMrun deleted the LH-88 branch December 12, 2025 11:53
@inishchith inishchith added e2e-test run-examples Run examples on the Pull Request labels Dec 12, 2025
@github-actions
Copy link

github-actions bot commented Dec 12, 2025

📦 Example workflows test results

  • This workflow runs all the examples in the examples directory.

Example Status Time Taken
application_sql COMPLETED 🟢 8.06 seconds
application_sql_with_custom_transformer COMPLETED 🟢 8.03 seconds
application_sql_miner COMPLETED 🟢 243.38 seconds
application_hello_world COMPLETED 🟢 5.03 seconds

This is an automatically generated file. Please do not edit directly.
Operating system: ubuntu-22.04

@github-actions
Copy link

github-actions bot commented Dec 12, 2025

📦 Example workflows test results

  • This workflow runs all the examples in the examples directory.

Example Status Time Taken
application_sql COMPLETED 🟢 16.16 seconds
application_sql_with_custom_transformer COMPLETED 🟢 8.36 seconds
application_sql_miner FAILED 🔴 243.81 seconds
application_hello_world COMPLETED 🟢 5.34 seconds

This is an automatically generated file. Please do not edit directly.
Operating system: windows-latest

@github-actions
Copy link

github-actions bot commented Dec 12, 2025

📦 Example workflows test results

  • This workflow runs all the examples in the examples directory.

Example Status Time Taken
application_sql COMPLETED 🟢 8.39 seconds
application_sql_with_custom_transformer COMPLETED 🟢 8.09 seconds
application_sql_miner FAILED 🔴 243.67 seconds
application_hello_world COMPLETED 🟢 5.03 seconds

This is an automatically generated file. Please do not edit directly.
Operating system: macOS-latest

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

Labels

e2e-test run-examples Run examples on the Pull Request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants