diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1ab1e8bd..66747ec3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,7 +16,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.11' + python-version: "3.11" - name: Install dependencies run: | @@ -52,7 +52,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.11' + python-version: "3.11" - name: Install dependencies run: | @@ -66,7 +66,7 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v4 - + - name: Install Git LFS run: git lfs install @@ -76,7 +76,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.11.12' + python-version: "3.11.12" - name: Install dependencies run: | @@ -99,7 +99,7 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v4 - + - name: Install Git LFS run: git lfs install @@ -109,7 +109,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.11.12' + python-version: "3.11.12" - name: Install dependencies run: | diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index cb8f9e90..95ea8d80 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -60,8 +60,8 @@ jobs: run: | chmod +x *.sh ./package.sh full - BUILD_NUMBER=$(grep 'BUILD =' build/_version.py | awk '{print $3}') - echo "ZIP_NAME=dynatrace_snowflake_observability_agent-${{ steps.get_version.outputs.VERSION }}.${BUILD_NUMBER}.zip" >> $GITHUB_OUTPUT + BUILD_NR=$(grep 'BUILD =' build/_version.py | awk '{print $3}') + echo "ZIP_NAME=dynatrace_snowflake_observability_agent-${{ steps.get_version.outputs.VERSION }}.${BUILD_NR}.zip" >> $GITHUB_OUTPUT echo "PDF_NAME=Dynatrace-Snowflake-Observability-Agent-${{ steps.get_version.outputs.VERSION }}.pdf" >> $GITHUB_OUTPUT - name: Upload build artifacts diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 00000000..63ed952a --- /dev/null +++ b/.prettierrc @@ -0,0 +1,6 @@ +{ + "tabWidth": 2, + "useTabs": false, + "printWidth": 140, + "proseWrap": "always" +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 12eb6589..95cbd1d1 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -18,6 +18,7 @@ "editor.formatOnPaste": true, "editor.tabSize": 2, "editor.defaultFormatter": "ms-python.black-formatter", + "editor.rulers": [140], "debug.javascript.terminalOptions": {}, "debug.javascript.debugByLinkOptions": "on", "black-formatter.args": [ @@ -123,6 +124,7 @@ "uuidgen", "venv", "Vidhya", + "viewsend", "Waltham", "weasyprint", "xdist", @@ -180,9 +182,16 @@ "editor.formatOnSave": false, "editor.defaultFormatter": null }, + "files.trimTrailingWhitespace": true, "files.associations": { ".sqlfluff": "ini" }, "markdown.extension.tableFormatter.normalizeIndentation": true, - "editor.indentSize": "tabSize" + "editor.indentSize": "tabSize", + "[yml]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[yaml]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + } } \ No newline at end of file diff --git a/.yamllint b/.yamllint index e90e242a..4119bf5c 100644 --- a/.yamllint +++ b/.yamllint @@ -2,18 +2,25 @@ extends: default rules: line-length: max: 140 - level: warning + level: error indentation: spaces: 2 - level: warning + level: error document-start: present: false trailing-spaces: - level: warning + level: error empty-lines: max: 2 - level: warning + level: error new-line-at-end-of-file: - level: warning + level: error brackets: - level: warning \ No newline at end of file + level: error + # GitHub Actions use "on" as a key, which conflicts with the truthy check. + truthy: disable + # Prettier and yamllint have conflicting comment spacing rules. + comments: disable +# Ignore virtual environment directories +ignore: | + .venv/ diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 98fc63f5..a3df8990 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -352,7 +352,7 @@ Example of task status bizevent payload. "event.type": "dsoa.task", "host.name": "snowflakecomputing.com", "service.name": "dynatrace", - "dsoa.run.context": "self-monitoring", + "dsoa.run.context": "self_monitoring", "dsoa.run.id": "2c8988a1b94d43aeaa11d3c83d45468b", "dsoa.task.exec.id": "2025-03-18 10:58:59.364252", "dsoa.task.exec.status": "STARTED", diff --git a/SEMANTICS.md b/SEMANTICS.md index 5a713d49..8d3d5fa4 100644 --- a/SEMANTICS.md +++ b/SEMANTICS.md @@ -37,6 +37,7 @@ | Identifier | Description | Example | |------------|-------------|---------| | dsoa.​run.​id | Unique ID of each execution of the Dynatrace Snowflake Observability Agent plugin. It can be used to differentiate between telemetry produced between two executions, e.g., to calculate the change in the system. | 4aa7c76c-e98c-4b8b-a5b3-a8a721bbde2d | +| observed_timestamp | The timestamp (in epoch nanoseconds) when the event was observed. | 1741768500000000000 | | snowflake.​event.​type | Type of (timestamp based) event | snowflake.table.update | @@ -139,8 +140,8 @@ All telemetry delivered by this plugin is reported as `dsoa.run.context == "data |------------|-------------|---------| | db.​user | The user who issued the query. | SYSTEM | | snowflake.​object.​ddl.​modified | A JSON array that specifies the objects that were associated with a write operation in the query. | { "DTAGENT_DB.APP.TMP_RECENT_QUERIES": { "objectColumns": "HISTOGRAM_METRICS, COUNTER_METRICS, START_TIME, STATUS_CODE, SESSION_ID, QUERY_ID, DIMENSIONS, END_TIME, NAME, ATTRIBUTES, PARENT_QUERY_ID", "objectDomain": "Table" } } | -| snowflake.​object.​ddl.​operation | The SQL keyword that specifies the operation on the table, view, or column:
- ALTER,
- CREATE,
- DROP,
- REPLACE,
- UNDROP. | REPLACE | -| snowflake.​object.​ddl.​properties | A JSON array that specifies the object or column properties when you create, modify, drop, or undrop the object or column. There are two types of properties: atomic and compound. | {"creationMode": "CREATE", "columns": {"ADD": ["ATTRIBUTE","JOB_ID"]}} | +| snowflake.​object.​ddl.​operation | The SQL keyword that specifies the operation on the table, view, or column:
- ALTER,
- CREATE,
- DROP,
- REPLACE,
- UNDROP. | REPLACE | +| snowflake.​object.​ddl.​properties | A JSON array that specifies the object or column properties when you create, modify, drop, or undrop the object or column. There are two types of properties: atomic and compound. | {"creationMode": "CREATE", "columns": {"ADD": ["ATTRIBUTE","JOB_ID"]}} | | snowflake.​object.​id | An identifier for the object, which is unique within a given account and domain. | 747545 | | snowflake.​object.​name | The fully qualified name of the object defined or modified by the DDL operation. | DTAGENT_DB.APP.TMP_RECENT_QUERIES | | snowflake.​object.​type | The domain of the object defined or modified by the DDL operation, which includes all objects that can be tagged and:
- MASKING POLICY,
- ROW ACCESS POLICY,
- TAG. | Table | diff --git a/docs/dashboards/costs-monitoring/costs-monitoring.yaml b/docs/dashboards/costs-monitoring/costs-monitoring.yaml index 2f83087b..946774e5 100644 --- a/docs/dashboards/costs-monitoring/costs-monitoring.yaml +++ b/docs/dashboards/costs-monitoring/costs-monitoring.yaml @@ -167,7 +167,7 @@ tiles: inputData: null "1": type: markdown - content: '# Resource Monitors' + content: "# Resource Monitors" davis: componentState: inputData: null @@ -330,19 +330,19 @@ tiles: rules: - id: 0 color: - Default: 'var(--dt-colors-charts-categorical-color-09-default, #649438)' + Default: "var(--dt-colors-charts-categorical-color-09-default, #649438)" comparator: < label: "" value: 50 - id: 1 color: - Default: 'var(--dt-colors-charts-categorical-color-14-default, #d56b1a)' + Default: "var(--dt-colors-charts-categorical-color-14-default, #d56b1a)" comparator: < label: "" value: 99 - id: 2 color: - Default: 'var(--dt-colors-charts-categorical-color-12-default, #cd3741)' + Default: "var(--dt-colors-charts-categorical-color-12-default, #cd3741)" comparator: ≥ label: "" value: 100 @@ -364,7 +364,7 @@ tiles: inputData: null "4": type: markdown - content: '# Warehouses' + content: "# Warehouses" davis: componentState: inputData: null @@ -407,19 +407,19 @@ tiles: rules: - id: 0 color: - Default: 'var(--dt-colors-charts-categorical-color-09-default, #649438)' + Default: "var(--dt-colors-charts-categorical-color-09-default, #649438)" comparator: = label: "" value: INFO - id: 1 color: - Default: 'var(--dt-colors-charts-categorical-color-14-default, #d56b1a)' + Default: "var(--dt-colors-charts-categorical-color-14-default, #d56b1a)" comparator: = label: "" value: WARN - id: 2 color: - Default: 'var(--dt-colors-charts-categorical-color-12-default, #cd3741)' + Default: "var(--dt-colors-charts-categorical-color-12-default, #cd3741)" comparator: = label: "" value: ERROR @@ -661,19 +661,19 @@ tiles: rules: - id: 0 color: - Default: 'var(--dt-colors-charts-categorical-color-09-default, #649438)' + Default: "var(--dt-colors-charts-categorical-color-09-default, #649438)" comparator: < label: "" value: 50 - id: 1 color: - Default: 'var(--dt-colors-charts-categorical-color-14-default, #d56b1a)' + Default: "var(--dt-colors-charts-categorical-color-14-default, #d56b1a)" comparator: < label: "" value: 99 - id: 2 color: - Default: 'var(--dt-colors-charts-categorical-color-12-default, #cd3741)' + Default: "var(--dt-colors-charts-categorical-color-12-default, #cd3741)" comparator: ≥ label: "" value: 100 @@ -782,7 +782,7 @@ tiles: visibleSections: VISUALIZATION "10": type: markdown - content: '# Slow queries' + content: "# Slow queries" davis: componentState: inputData: null @@ -1181,7 +1181,10 @@ tiles: deployment.environment, snowflake.warehouse.name } - | fieldsAdd warehouse_events = record( ts = start_events[], event_delay = finish_events[] - start_events[], warehouse_action = warehouse_action[]) + | fieldsAdd warehouse_events = record( + ts = start_events[], + event_delay = finish_events[] - start_events[], + warehouse_action = warehouse_action[]) | expand warehouse_events | fields event_timestamp = warehouse_events[ts], deployment.environment, diff --git a/docs/dashboards/self-monitoring/self-monitoring.yaml b/docs/dashboards/self-monitoring/self-monitoring.yaml index 678567c3..820a8926 100644 --- a/docs/dashboards/self-monitoring/self-monitoring.yaml +++ b/docs/dashboards/self-monitoring/self-monitoring.yaml @@ -53,7 +53,8 @@ variables: | filter in(deployment.environment, array($Accounts)) | filter matchesPattern(db.query.text, """'call DTAGENT' ('_' LD:tag)? '_DB.APP.DTAGENT(ARRAY_CONSTRUCT(' ARRAY{SQS:plugin_name ', '?}{1,}:plugin_names '))'""") - | parse `db.query.text`, """'call DTAGENT' ('_' LD:env_tag)? '_DB.APP.DTAGENT(ARRAY_CONSTRUCT(' ARRAY{SQS:plugin_name ', '?}{1,}:plugin_names '))'""" + | parse `db.query.text`, + """'call DTAGENT' ('_' LD:env_tag)? '_DB.APP.DTAGENT(ARRAY_CONSTRUCT(' ARRAY{SQS:plugin_name ', '?}{1,}:plugin_names '))'""" | expand plugin_name = plugin_names | fields plugin_name | dedup plugin_name @@ -73,7 +74,8 @@ variables: | filter in(deployment.environment, array($Accounts)) | filter matchesPattern(db.query.text, """'call DTAGENT' ('_' LD:tag)? '_DB.APP.DTAGENT(ARRAY_CONSTRUCT(' ARRAY{SQS:plugin_name ', '?}{1,}:plugin_names '))'""") - | parse `db.query.text`, """'call DTAGENT' ('_' LD:env_tag)? '_DB.APP.DTAGENT(ARRAY_CONSTRUCT(' ARRAY{SQS:plugin_name ', '?}{1,}:plugin_names '))'""" + | parse `db.query.text`, + """'call DTAGENT' ('_' LD:env_tag)? '_DB.APP.DTAGENT(ARRAY_CONSTRUCT(' ARRAY{SQS:plugin_name ', '?}{1,}:plugin_names '))'""" | expand plugin_name = plugin_names | fields plugin_name | filter in(plugin_name, array($Plugin_Names)) @@ -147,7 +149,7 @@ tiles: query: |- fetch bizevents | filter db.system == "snowflake" - | filter dsoa.run.context == "self-monitoring" + | filter dsoa.run.context == "self_monitoring" | filter in(deployment.environment, array($Accounts)) | filter in(dsoa.task.name, array($Plugin_Names)) | sort timestamp asc @@ -215,7 +217,8 @@ tiles: | filter snowflake.query.execution_status != "SUCCESS" | filter matchesPattern(db.query.text, """'call DTAGENT' ('_' LD:tag)? '_DB.APP.DTAGENT(ARRAY_CONSTRUCT(' ARRAY{SQS:plugin_name ', '?}{1,}:plugin_names '))'""") - | parse `db.query.text`, """'call DTAGENT' ('_' LD:env_tag)? '_DB.APP.DTAGENT(ARRAY_CONSTRUCT(' ARRAY{SQS:plugin_name ', '?}{1,}:plugin_names '))'""" + | parse `db.query.text`, + """'call DTAGENT' ('_' LD:env_tag)? '_DB.APP.DTAGENT(ARRAY_CONSTRUCT(' ARRAY{SQS:plugin_name ', '?}{1,}:plugin_names '))'""" | expand plugin_name = plugin_names | fields plugin_name, timestamp, snowflake.query.execution_status | makeTimeseries count(), by: { @@ -259,7 +262,7 @@ tiles: query: |- fetch bizevents | filter db.system == "snowflake" - | filter dsoa.run.context == "self-monitoring" + | filter dsoa.run.context == "self_monitoring" | filter in(deployment.environment, array($Accounts)) | filter in(dsoa.task.name, array($Plugin_Names)) | sort timestamp asc @@ -305,7 +308,7 @@ tiles: query: |- fetch bizevents | filter db.system == "snowflake" - | filter dsoa.run.context == "self-monitoring" + | filter dsoa.run.context == "self_monitoring" | filter in(deployment.environment, array($Accounts)) | filter in(dsoa.task.name, array($Plugin_Names)) | sort timestamp asc @@ -388,7 +391,7 @@ tiles: query: |- fetch bizevents | filter db.system == "snowflake" - | filter dsoa.run.context == "self-monitoring" + | filter dsoa.run.context == "self_monitoring" | filter in(deployment.environment, array($Accounts)) | filter in(dsoa.task.name, array($Plugin_Names)) | sort timestamp desc @@ -456,7 +459,8 @@ tiles: | filter in(deployment.environment, array($Accounts)) | filter matchesPattern(db.query.text, """'call DTAGENT' ('_' LD:tag)? '_DB.APP.DTAGENT(ARRAY_CONSTRUCT(' ARRAY{SQS:plugin_name ', '?}{1,}:plugin_names '))'""") - | parse `db.query.text`, """'call DTAGENT' ('_' LD:env_tag)? '_DB.APP.DTAGENT(ARRAY_CONSTRUCT(' ARRAY{SQS:plugin_name ', '?}{1,}:plugin_names '))'""" + | parse `db.query.text`, + """'call DTAGENT' ('_' LD:env_tag)? '_DB.APP.DTAGENT(ARRAY_CONSTRUCT(' ARRAY{SQS:plugin_name ', '?}{1,}:plugin_names '))'""" | fieldsAdd plugins_count = arraySize(plugin_names) | expand plugin_name = plugin_names | filter in(plugin_name, array($Plugin_Names)) diff --git a/docs/debug/active-queries-faq/dsoa-active-queries-test-dashboard.json b/docs/debug/active-queries-faq/dsoa-active-queries-test-dashboard.json index b7a54d20..55f39b7a 100644 --- a/docs/debug/active-queries-faq/dsoa-active-queries-test-dashboard.json +++ b/docs/debug/active-queries-faq/dsoa-active-queries-test-dashboard.json @@ -21,7 +21,7 @@ "from": "now()-24h", "to": "now()" }, - "value": "fetch bizevents\n| filter db.system == \"snowflake\"\n| filter dsoa.run.context == \"self-monitoring\"\n| filter deployment.environment == \"PROD\" // <-- set to your configuration CORE.DEPLOYMENT_ENVIRONMENT\n| filter dsoa.task.name == \"active_queries\"\n| sort timestamp asc\n| summarize {\n timestamp = takeFirst(timestamp) + 2h,\n snowagent.run.duration = max(timestamp) - min(timestamp),\n count = count()\n}, by: {\n deployment.environment,\n deployment.environment.tag = coalesce(deployment.environment.tag, env_tag),\n dsoa.task.exec.id,\n dsoa.task.name\n}\n| filter count > 1\n| makeTimeseries {\n snowagent.run.duration = sum(snowagent.run.duration)\n}, by: {\n deployment.environment,\n dsoa.run.context = dsoa.task.name\n}" + "value": "fetch bizevents\n| filter db.system == \"snowflake\"\n| filter dsoa.run.context == \"self_monitoring\"\n| filter deployment.environment == \"PROD\" // <-- set to your configuration CORE.DEPLOYMENT_ENVIRONMENT\n| filter dsoa.task.name == \"active_queries\"\n| sort timestamp asc\n| summarize {\n timestamp = takeFirst(timestamp) + 2h,\n snowagent.run.duration = max(timestamp) - min(timestamp),\n count = count()\n}, by: {\n deployment.environment,\n deployment.environment.tag = coalesce(deployment.environment.tag, env_tag),\n dsoa.task.exec.id,\n dsoa.task.name\n}\n| filter count > 1\n| makeTimeseries {\n snowagent.run.duration = sum(snowagent.run.duration)\n}, by: {\n deployment.environment,\n dsoa.run.context = dsoa.task.name\n}" }, "visualizationSettings": { "thresholds": [], diff --git a/send_bizevent.sh b/send_bizevent.sh index d750aa8c..c87e3abc 100755 --- a/send_bizevent.sh +++ b/send_bizevent.sh @@ -44,21 +44,34 @@ elif [ "$(./get_config_key.sh plugins.self_monitoring.send_bizevents_on_deploy)" PARAM="full_deployment" fi + VERSION="$(grep 'VERSION =' build/700_dtagent.sql | awk -F'"' '{print $2}')" + BUILD="$(grep 'BUILD =' build/700_dtagent.sql | awk -F' ' '{print $3}')" + if ! curl -f -X POST "https://${DT_ADDRESS}/api/v2/bizevents/ingest" \ -H "Authorization: Api-Token ${DTAGENT_TOKEN}" \ -H 'Content-Type: application/json' \ - -d "{ - \"event.type\": \"CUSTOM_DEPLOYMENT\", - \"event.title\": \"${TITLE}\", - \"db.system\": \"snowflake\", - \"deployment.environment\": \"$(./get_config_key.sh core.deployment_environment)\", - \"host.name\": \"$(./get_config_key.sh core.snowflake_host_name)\", - \"telemetry.exporter.name\": \"dynatrace.snowagent\", - \"telemetry.exporter.version\": \"$(grep 'VERSION =' build/700_dtagent.sql | awk -F'"' '{print $2}')\", - \"dsoa.deployment.parameter\": \"${PARAM}\", - \"dsoa.deployment.status\": \"${STATUS}\", - \"dsoa.deployment.id\": \"${DEPLOYMENT_ID}\" - }" >/dev/null 2>&1; then + -d @<(cat </dev/null 2>&1; then exit 1 fi fi diff --git a/src/build/update_docs.py b/src/build/update_docs.py index 2728dcb8..4f6147d6 100644 --- a/src/build/update_docs.py +++ b/src/build/update_docs.py @@ -169,7 +169,7 @@ def _generate_plugins_info(dtagent_plugins_path: str) -> Tuple[str, List]: def _generate_semantics_section(dtagent_conf_path: str, dtagent_plugins_path: str) -> Tuple[str, List]: """Generates semantics sections for .md file.""" - from src.dtagent.context import CONTEXT_NAME + from src.dtagent.context import RUN_CONTEXT_KEY def __contains_key(d: Dict, key: str) -> bool: """Returns True if there is at least on key with given name @@ -228,9 +228,11 @@ def __contains_key(d: Dict, key: str) -> bool: __content += f"[Show plugin description](#{plugin_name}_info_sec)\n\n" if no_global_context_name: - __content += f"This plugin delivers telemetry in multiple contexts. To filter by one of plugin's context names (reported as `{CONTEXT_NAME}`), please check the `Context Name` column below.\n\n" + __content += f"This plugin delivers telemetry in multiple contexts. To filter by one of plugin's context names (reported as `{RUN_CONTEXT_KEY}`), please check the `Context Name` column below.\n\n" else: - __content += f'All telemetry delivered by this plugin is reported as `{CONTEXT_NAME} == "{plugin_name}"`.\n\n' + __content += ( + f'All telemetry delivered by this plugin is reported as `{RUN_CONTEXT_KEY} == "{plugin_name}"`.\n\n' + ) __content += plugin_semantics diff --git a/src/dtagent.conf/bom.yml b/src/dtagent.conf/bom.yml index 7fd14049..55c9daae 100644 --- a/src/dtagent.conf/bom.yml +++ b/src/dtagent.conf/bom.yml @@ -57,7 +57,7 @@ references: privileges: IMPORTED PRIVILEGES ON DATABASE granted to: DTAGENT_VIEWER - name: ACCOUNT - privileges: + privileges: - MONITOR - MONITOR USAGE - MONITOR EXECUTION @@ -72,13 +72,11 @@ references: privileges: MANAGE GRANTS granted to: DTAGENT_ADMIN - name: ACCOUNT - privileges: + privileges: - EXECUTE TASK granted to: DTAGENT_VIEWER - name: DATABASE DTAGENT_DB - privileges: + privileges: - OPERATE on all TASKS - OPERATE on future TASKS granted to: DTAGENT_VIEWER - - diff --git a/src/dtagent.conf/instruments-def.yml b/src/dtagent.conf/instruments-def.yml index 16874363..bc903eb9 100644 --- a/src/dtagent.conf/instruments-def.yml +++ b/src/dtagent.conf/instruments-def.yml @@ -37,22 +37,31 @@ dimensions: __description: "The version of the telemetry exporter." __example: "0.8.0.17308403933" dsoa.run.context: - __description: "The name of the Dynatrace Snowflake Observability Agent plugin (or part of plugin) used to produce the telemetry (logs, traces, metrics, or events)." + __description: + "The name of the Dynatrace Snowflake Observability Agent plugin (or part of plugin) used to produce the telemetry (logs, traces, + metrics, or events)." __example: "query_history" # * Attribute definitions # * KEY - will be matched against ATTRIBUTES object with measurements prepared for sending -# * VALUE[description] - description of the attributes - in the future we should rather update semantic dictionary instead of pushing it constantly +# * VALUE[description] - description of the attributes - +# in the future we should rather update semantic dictionary instead of pushing it constantly # * VALUE[example] - the example of attribute value attributes: dsoa.run.id: - __description: "Unique ID of each execution of the Dynatrace Snowflake Observability Agent plugin. It can be used to differentiate between telemetry produced between two executions, e.g., to calculate the change in the system." + __description: + "Unique ID of each execution of the Dynatrace Snowflake Observability Agent plugin. It can be used to differentiate between telemetry + produced between two executions, e.g., to calculate the change in the system." __example: "4aa7c76c-e98c-4b8b-a5b3-a8a721bbde2d" snowflake.event.type: __description: "Type of (timestamp based) event" __example: "snowflake.table.update" + observed_timestamp: + __description: "The timestamp (in epoch nanoseconds) when the event was observed." + __example: "1741768500000000000" # * Metric definitions # * KEY - will be matched against METRICS object with measurements prepared for sending -# * VALUE[description] - description of the metrics - in the future we should rather update semantic dictionary instead of pushing it constantly +# * VALUE[description] - description of the metrics - +# in the future we should rather update semantic dictionary instead of pushing it constantly # * VALUE[unit] - the unit of the metric metrics: {} diff --git a/src/dtagent.sql/010_schema_config.sql b/src/dtagent.sql/010_schema_config.sql index f3967689..7c3946cc 100644 --- a/src/dtagent.sql/010_schema_config.sql +++ b/src/dtagent.sql/010_schema_config.sql @@ -28,6 +28,4 @@ use role DTAGENT_ADMIN; use database DTAGENT_DB; use warehouse DTAGENT_WH; create schema if not exists CONFIG; -grant usage on schema CONFIG to role DTAGENT_VIEWER; - -show grants on schema CONFIG; \ No newline at end of file +grant usage on schema CONFIG to role DTAGENT_VIEWER; \ No newline at end of file diff --git a/src/dtagent/__init__.py b/src/dtagent/__init__.py index f05ec7c5..479b053d 100644 --- a/src/dtagent/__init__.py +++ b/src/dtagent/__init__.py @@ -38,7 +38,8 @@ from dtagent.otel.events.generic import GenericEvents from dtagent.otel.events.davis import DavisEvents from dtagent.otel.events.bizevents import BizEvents -from dtagent.context import get_context_name_and_run_id +from dtagent.version import VERSION +from dtagent.context import get_context_name_and_run_id, RUN_VERSION_KEY # COMPILE_REMOVE from dtagent.util import get_now_timestamp_formatted, is_regular_mode ##endregion COMPILE_REMOVE @@ -93,7 +94,7 @@ def __init__(self, session: snowpark.Session) -> None: self._session = session if is_regular_mode(session): - session.query_tag = "dsoa:" + get_now_timestamp_formatted() + session.query_tag = json.dumps({RUN_VERSION_KEY: str(VERSION)}) self._configuration = self._get_config(session) @@ -146,7 +147,9 @@ def _get_config(self, session: snowpark.Session) -> Configuration: """ return Configuration(session) - def report_execution_status(self, status: str, task_name: str, exec_id: str, details_dict: Optional[dict] = None): + def report_execution_status( + self, status: str, task_name: str, exec_id: str, details_dict: Optional[dict] = None, plugin_name: str = None + ): """Sends BizEvent for given task with given status if BizEvents are allowed and send_bizevents_on_run is enabled""" if "biz_events" in self.telemetry_allowed and self._configuration.get( @@ -163,7 +166,7 @@ def report_execution_status(self, status: str, task_name: str, exec_id: str, det bizevents_sent = self._biz_events.report_via_api( query_data=[data_dict | (details_dict or {})], event_type="dsoa.task", - context=get_context_name_and_run_id("self-monitoring"), + context=get_context_name_and_run_id(plugin_name=plugin_name or task_name, context_name="self_monitoring", run_id=exec_id), is_data_structured=False, ) bizevents_sent += self._biz_events.flush_events() diff --git a/src/dtagent/agent.py b/src/dtagent/agent.py index b6ac552d..90eb6ead 100644 --- a/src/dtagent/agent.py +++ b/src/dtagent/agent.py @@ -109,11 +109,16 @@ def process(self, sources: List, run_proc: bool = True) -> Dict[str, Union[Dict[ Example: { - "active_queries": { - "entries": 10, - "log_lines": 100, - "metrics": 5, - "events": 2 + "plugin_name": { + "dsoa.run.results": { + "context_name": { + "entries": 10, + "log_lines": 100, + "metrics": 5, + "events": 2 + } + }, + "dsoa.run.id": "uuid_string" }, "some_other_plugin": "not_implemented" } @@ -123,6 +128,7 @@ def process(self, sources: List, run_proc: bool = True) -> Dict[str, Union[Dict[ import inspect from dtagent import LOG # COMPILE_REMOVE from dtagent.otel import NO_OP_TELEMETRY # COMPILE_REMOVE + from dtagent.context import RUN_PLUGIN_KEY, RUN_ID_KEY, RUN_VERSION_KEY # COMPILE_REMOVE results: dict = {} @@ -130,12 +136,12 @@ def process(self, sources: List, run_proc: bool = True) -> Dict[str, Union[Dict[ from dtagent.plugins import _get_plugin_class # COMPILE_REMOVE c_source = _get_plugin_class(source) - exec_id = get_now_timestamp_formatted() - - self.report_execution_status(status="STARTED", task_name=source, exec_id=exec_id) + run_id = str(uuid.uuid4().hex) if is_regular_mode(self._session): - self._session.query_tag = f"dsoa.version:{str(VERSION)}.plugin:{c_source.__name__}.{exec_id}" + self._session.query_tag = json.dumps({RUN_VERSION_KEY: str(VERSION), RUN_PLUGIN_KEY: c_source.__name__, RUN_ID_KEY: run_id}) + + self.report_execution_status(status="STARTED", task_name=source, exec_id=run_id) plugin_telemetry_allowed = ( set( @@ -152,6 +158,7 @@ def process(self, sources: List, run_proc: bool = True) -> Dict[str, Union[Dict[ # try: results[source] = c_source( + plugin_name=source, session=self._session, configuration=self._configuration, logs=self._logs if "logs" in plugin_telemetry_allowed else NO_OP_TELEMETRY, @@ -159,13 +166,14 @@ def process(self, sources: List, run_proc: bool = True) -> Dict[str, Union[Dict[ metrics=self._metrics if "metrics" in plugin_telemetry_allowed else NO_OP_TELEMETRY, events=self._events if "events" in plugin_telemetry_allowed else NO_OP_TELEMETRY, bizevents=self._biz_events if "biz_events" in plugin_telemetry_allowed else NO_OP_TELEMETRY, - ).process(run_proc) + ).process(run_id, run_proc) # - self.report_execution_status(status="FINISHED", task_name=source, exec_id=exec_id) + + self.report_execution_status(status="FINISHED", task_name=source, exec_id=run_id, details_dict=results[source]) except RuntimeError as e: - self.handle_interrupted_run(source, exec_id, str(e)) + self.handle_interrupted_run(source, run_id, str(e)) else: - self.report_execution_status(status="FAILED", task_name=source, exec_id=exec_id) + self.report_execution_status(status="FAILED", task_name=source, exec_id=run_id) results[source] = {"not_implemented": c_source} LOG.warning(f"""Requested measuring source {source} that is not implemented: {results[source]}""") diff --git a/src/dtagent/connector.py b/src/dtagent/connector.py index a57b4007..95f1499b 100644 --- a/src/dtagent/connector.py +++ b/src/dtagent/connector.py @@ -25,10 +25,11 @@ # SOFTWARE. # # +from pdb import run from dtagent import AbstractDynatraceSnowAgentConnector from dtagent.config import Configuration -from dtagent.util import get_now_timestamp_formatted +from dtagent.util import get_now_timestamp_formatted, is_regular_mode from dtagent.otel.instruments import Instruments from dtagent.otel.logs import Logs from dtagent.otel.spans import Spans @@ -107,13 +108,18 @@ class TelemetrySender(AbstractDynatraceSnowAgentConnector, Plugin): """Telemetry sender class delivers possibility of sending custom data from Snowflake to Grail, not being limited by plugins.""" - def __init__(self, session: snowpark.Session, params: dict): + def __init__(self, session: snowpark.Session, params: dict, exec_id: str) -> None: """ Initialization for TelemetrySender class. + + Args: + session (snowpark.Session): snowflake snowpark session + params (dict): parameters for telemetry sending + exec_id (str): unique execution identifier """ from dtagent.context import get_context_name_and_run_id # COMPILE_REMOVE - Plugin.__init__(self, session=session) + Plugin.__init__(self, plugin_name="telemetry_sender", session=session) AbstractDynatraceSnowAgentConnector.__init__(self, session) self._params = params or {} @@ -132,10 +138,10 @@ def __init__(self, session: snowpark.Session, params: dict): # in case of auto-mode disabled we can send the source as bizevents self._send_biz_events = next((self._params[key] for key in ["biz_events", "bizevents"] if key in self._params), False) - self.__context_name = self._params.get("context", "telemetry_sender") - self.__context = get_context_name_and_run_id(self.__context_name) + self.__context_name = self._params.get("context", self._plugin_name) + self.__context = get_context_name_and_run_id(plugin_name=self._plugin_name, context_name=self.__context_name, run_id=exec_id) - def process(self, run_proc: bool = True) -> Dict[str, int]: + def process(self, run_id: str, run_proc: bool = True) -> Dict[str, int]: """we don't use it but Plugin marks it as abstract""" return {} @@ -164,7 +170,7 @@ def _get_source_rows(self, source: Union[str, dict, list]) -> Generator[Dict, No for row_dict in source: yield row_dict - def send_data(self, source_data: Union[str, dict, list], exec_id: str = get_now_timestamp_formatted()) -> Dict[str, int]: + def send_data(self, source_data: Union[str, dict, list]) -> Dict[str, int]: """Sends telemetry data from given source based on the parameters provided to the stored procedure Args: @@ -175,23 +181,35 @@ def send_data(self, source_data: Union[str, dict, list], exec_id: str = get_now_ Example: { - "entries": 10, - "log_lines": 10, - "metrics": 5, - "events": 5, - "biz_events": 2, - "davis_events": 0, + "dsoa.run.results": { + "telemetry_sender": { + "entries": 10, + "log_lines": 10, + "metrics": 5, + "events": 5, + "biz_events": 2, + "davis_events": 0, + } + }, + "dsoa.run.id": "uuid_string" } """ from dtagent.otel.events import EventType # COMPILE_REMOVE + from dtagent.context import RUN_ID_KEY, RUN_PLUGIN_KEY, RUN_VERSION_KEY, RUN_RESULTS_KEY # COMPILE_REMOVE + + exec_id = self.__context[RUN_ID_KEY] + + if is_regular_mode(self._session): + self._session.query_tag = json.dumps({RUN_VERSION_KEY: str(VERSION), RUN_PLUGIN_KEY: self.__context_name, RUN_ID_KEY: exec_id}) - self.report_execution_status(status="STARTED", task_name=self.__context_name, exec_id=exec_id) + self.report_execution_status(status="STARTED", task_name=self.__context_name, exec_id=exec_id, plugin_name=self._plugin_name) entries_cnt, logs_cnt, metrics_cnt, events_cnt, bizevents_cnt, davis_events_cnt = (0, 0, 0, 0, 0, 0) if self._auto_mode: entries_cnt, logs_cnt, metrics_cnt, events_cnt = self._log_entries( lambda: self._get_source_rows(source_data), self.__context_name, + run_uuid=exec_id, report_logs=self._send_logs, report_metrics=self._send_metrics, report_timestamp_events=self._send_events, @@ -231,7 +249,9 @@ def send_data(self, source_data: Union[str, dict, list], exec_id: str = get_now_ except ValueError as e: from dtagent import LOG # COMPILE_REMOVE - self.report_execution_status(status="FAILED", task_name=self.__context_name, exec_id=exec_id) + self.report_execution_status( + status="FAILED", task_name=self.__context_name, exec_id=exec_id, plugin_name=self._plugin_name + ) LOG.error("Could not send event due to %s", e) entries_cnt += 1 @@ -267,34 +287,39 @@ def send_data(self, source_data: Union[str, dict, list], exec_id: str = get_now_ davis_events_cnt += self._davis_events.flush_events() results_dict = { - "entries": entries_cnt, - "log_lines": logs_cnt, - "metrics": metrics_cnt, - "events": events_cnt, - "biz_events": bizevents_cnt, - "davis_events": davis_events_cnt, + self.__context_name: { + "entries": entries_cnt, + "log_lines": logs_cnt, + "metrics": metrics_cnt, + "events": events_cnt, + "biz_events": bizevents_cnt, + "davis_events": davis_events_cnt, + } } - - self.report_execution_status(status="FINISHED", task_name=self.__context_name, exec_id=exec_id) - self._report_execution( self.__context_name, get_now_timestamp_formatted(), None, results_dict, + run_id=exec_id, + ) + exec_results = {RUN_RESULTS_KEY: results_dict, RUN_ID_KEY: self.__context[RUN_ID_KEY]} + + self.report_execution_status( + status="FINISHED", task_name=self.__context_name, exec_id=exec_id, details_dict=exec_results, plugin_name=self._plugin_name ) - return results_dict + return exec_results def main(session: snowpark.Session, source: Union[str, dict, list], params: dict) -> str: """ MAIN entry to this stored procedure - this is where the fun begins """ - sender = TelemetrySender(session, params) - exec_id = get_now_timestamp_formatted() + exec_id = str(uuid.uuid4().hex) + sender = TelemetrySender(session, params, exec_id) try: - results = sender.send_data(source, exec_id) + results = sender.send_data(source) except RuntimeError as e: sender.handle_interrupted_run(source, exec_id, str(e)) diff --git a/src/dtagent/context.py b/src/dtagent/context.py index 30e0b165..267a4ee6 100644 --- a/src/dtagent/context.py +++ b/src/dtagent/context.py @@ -27,22 +27,23 @@ ##endregion COMPILE_REMOVE +from multiprocessing.pool import RUN from typing import Dict, Optional -CONTEXT_NAME = "dsoa.run.context" -RUN_ID_NAME = "dsoa.run.id" +RUN_CONTEXT_KEY = "dsoa.run.context" +RUN_ID_KEY = "dsoa.run.id" +RUN_RESULTS_KEY = "dsoa.run.results" +RUN_PLUGIN_KEY = "dsoa.run.plugin" +RUN_VERSION_KEY = "dsoa.run.version" -def get_context_name_and_run_id(context_name: str, run_id: Optional[str] = None) -> Dict[str, str]: +def get_context_name_and_run_id(plugin_name: str, context_name: str, run_id: str) -> Dict[str, str]: """Generates the complete context dictionary based on the given name and optional run ID""" import uuid - return { - CONTEXT_NAME: context_name, - RUN_ID_NAME: run_id or str(uuid.uuid4().hex), - } + return {RUN_PLUGIN_KEY: plugin_name, RUN_CONTEXT_KEY: context_name, RUN_ID_KEY: run_id} def get_context_name(context_name: Optional[str] = None) -> Dict[str, str]: """Generates the context dictionary based on the given context name if provided, otherwise returns empty dict""" - return {CONTEXT_NAME: context_name} if context_name else {} + return {RUN_CONTEXT_KEY: context_name} if context_name else {} diff --git a/src/dtagent/otel/events/__init__.py b/src/dtagent/otel/events/__init__.py index 3bf08ecc..78aa8fd1 100644 --- a/src/dtagent/otel/events/__init__.py +++ b/src/dtagent/otel/events/__init__.py @@ -36,7 +36,7 @@ import requests -from dtagent.context import CONTEXT_NAME +from dtagent.context import RUN_CONTEXT_KEY from dtagent.otel import _log_warning from dtagent.otel.otel_manager import OtelManager from dtagent.util import StringEnum, get_timestamp_in_ms diff --git a/src/dtagent/otel/events/bizevents.py b/src/dtagent/otel/events/bizevents.py index 17978e99..4adaeaa6 100644 --- a/src/dtagent/otel/events/bizevents.py +++ b/src/dtagent/otel/events/bizevents.py @@ -33,7 +33,7 @@ import requests -from dtagent.context import CONTEXT_NAME +from dtagent.context import RUN_CONTEXT_KEY from dtagent.otel import _log_warning from dtagent.otel.events import EventType, AbstractEvents from dtagent.otel.otel_manager import OtelManager @@ -86,7 +86,7 @@ def _pack_event_data( { "app.version": self._resource_attributes.get("telemetry.exporter.version", "0.0.0"), "app.short_version": VERSION, - "app.bundle": _context.get(CONTEXT_NAME, "bizevents"), + "app.bundle": _context.get(RUN_CONTEXT_KEY, "bizevents"), "app.id": "dynatrace.snowagent", } | self._resource_attributes diff --git a/src/dtagent/otel/events/davis.py b/src/dtagent/otel/events/davis.py index 7e22bc43..758b7018 100644 --- a/src/dtagent/otel/events/davis.py +++ b/src/dtagent/otel/events/davis.py @@ -35,7 +35,7 @@ import requests -from dtagent.context import CONTEXT_NAME +from dtagent.context import RUN_CONTEXT_KEY from dtagent.otel import _log_warning from dtagent.otel.otel_manager import OtelManager from dtagent.otel.events import EventType, AbstractEvents diff --git a/src/dtagent/otel/events/generic.py b/src/dtagent/otel/events/generic.py index fe1fcdbe..57020ce1 100644 --- a/src/dtagent/otel/events/generic.py +++ b/src/dtagent/otel/events/generic.py @@ -35,7 +35,7 @@ import requests -from dtagent.context import CONTEXT_NAME +from dtagent.context import RUN_CONTEXT_KEY from dtagent.otel import _log_warning from dtagent.otel.otel_manager import OtelManager from dtagent.otel.events import EventType, AbstractEvents diff --git a/src/dtagent/plugins/__init__.py b/src/dtagent/plugins/__init__.py index a99f7dcb..c0ee41d4 100644 --- a/src/dtagent/plugins/__init__.py +++ b/src/dtagent/plugins/__init__.py @@ -52,7 +52,7 @@ from dtagent.otel.logs import Logs from dtagent.otel.spans import Spans from dtagent.otel.metrics import Metrics -from dtagent.context import CONTEXT_NAME, get_context_name_and_run_id +from dtagent.context import RUN_CONTEXT_KEY, get_context_name_and_run_id ##endregion COMPILE_REMOVE @@ -67,6 +67,7 @@ class Plugin(ABC): def __init__( self, *, + plugin_name: str, session: snowpark.Session, logs: Optional[Logs] = None, spans: Optional[Spans] = None, @@ -77,6 +78,7 @@ def __init__( ): """Sets session variables.""" + self._plugin_name = plugin_name self._session = session if logs is not None: @@ -127,8 +129,8 @@ def _get_table_rows(self, t_data: str) -> Generator[Dict, None, None]: yield row_dict - def _report_execution(self, measurements_source: str, last_timestamp, last_id, entries_count: dict): - __context = get_context_name_and_run_id("self_monitoring") + def _report_execution(self, measurements_source: str, last_timestamp, last_id, entries_count: dict, run_id: str): + __context = get_context_name_and_run_id(plugin_name=self._plugin_name, context_name="self_monitoring", run_id=run_id) # we cannot use last timestamp when sending logs to DT, because when it is set to snowpark.current_timestamp, the value is taken from a snowflake table # for DT it would look like 'Column[current_timestamp]' @@ -157,8 +159,8 @@ def _process_span_rows( # pylint: disable=R0913 f_entry_generator: Callable, view_name: str, context_name: str, + run_uuid: str, *, - run_uuid: str = str(uuid.uuid4().hex), query_id_col_name: str = "QUERY_ID", parent_query_id_col_name: str = "PARENT_QUERY_ID", log_completion: bool = True, @@ -197,7 +199,7 @@ def _process_span_rows( # pylint: disable=R0913 logs_sent = 0 metrics_sent = 0 - __context = get_context_name_and_run_id(context_name, run_uuid) + __context = get_context_name_and_run_id(plugin_name=self._plugin_name, context_name=context_name, run_id=run_uuid) for row_dict in f_entry_generator(): query_id = row_dict.get(query_id_col_name, None) @@ -244,6 +246,7 @@ def _process_span_rows( # pylint: disable=R0913 "processing_errors_count": processing_errors_count, "span_events_added_count": span_events_added, }, + run_id=run_uuid, ) if report_status: @@ -293,7 +296,9 @@ def _process_row( row_id = row.get(row_id_col, None) LOG.log(LL_TRACE, "Processing row with id = %s", row_id) - metrics_sent, metrics_cnt = self._metrics.discover_report_metrics(row, "START_TIME", context_name=context.get(CONTEXT_NAME, None)) + metrics_sent, metrics_cnt = self._metrics.discover_report_metrics( + row, "START_TIME", context_name=context.get(RUN_CONTEXT_KEY, None) + ) if not metrics_sent: processing_errors.append(f"Problem sending row {row_id} as metric") @@ -336,7 +341,7 @@ def report_log(self, row_dict: Dict, __context: Dict, log_level: int) -> bool: event_dict = _cleanup_dict({"timestamp": self.processed_last_timestamp, **log_dict}) self._logs.send_log( - row_dict.get("_MESSAGE", __context.get(CONTEXT_NAME)), + row_dict.get("_MESSAGE", __context.get(RUN_CONTEXT_KEY)), extra=event_dict, log_level=log_level, context=__context, @@ -396,8 +401,8 @@ def _log_entries( # pylint: disable=R0913 self, f_entry_generator: Callable[[Dict, None], None], context_name: str, + run_uuid: str, *, - run_uuid: str = str(uuid.uuid4().hex), report_logs: bool = True, report_metrics: bool = True, report_timestamp_events: bool = True, @@ -463,7 +468,7 @@ def _log_entries( # pylint: disable=R0913 if f_event_timestamp_payload_prepare is None: f_event_timestamp_payload_prepare = self.prepare_timestamp_event - __context = get_context_name_and_run_id(context_name, run_uuid) + __context = get_context_name_and_run_id(plugin_name=self._plugin_name, context_name=context_name, run_id=run_uuid) self.processed_last_timestamp = None processed_entries_cnt = 0 @@ -558,28 +563,26 @@ def _log_entries( # pylint: disable=R0913 entries_dict["processed_metrics_cnt"] = processed_metrics_cnt if log_completion: - self._report_execution( - context_name, - str(self.processed_last_timestamp), - None, - entries_dict, - ) + self._report_execution(context_name, str(self.processed_last_timestamp), None, entries_dict, run_id=run_uuid) return processed_entries_cnt, processed_logs_cnt, processed_metrics_cnt, processed_events_cnt @abstractmethod - def process(self, run_proc: bool = True) -> Dict[str, Dict[str, int]]: + def process(self, run_id: str, run_proc: bool = True) -> Dict[str, Dict[str, int]]: """ Abstract method for plugin processing. Args: + run_id (str): unique run identifier run_proc (bool): indicator whether processing should be logged as completed Returns: Dict[str,int]: dictionary with telemetry counts Example: - { "context_name": + { + "dsoa.run.results": { + "context_name": { "entries": 10, "log_lines": 10, @@ -587,7 +590,9 @@ def process(self, run_proc: bool = True) -> Dict[str, Dict[str, int]]: "events": 5, "biz_events": 2, "davis_events": 0, - } + }, + }, + "dsoa.run.id": "uuid_string" } """ # Implement method process() at plugins diff --git a/src/dtagent/plugins/active_queries.config/bom.yml b/src/dtagent/plugins/active_queries.config/bom.yml index cdaed26a..4a18bc4f 100644 --- a/src/dtagent/plugins/active_queries.config/bom.yml +++ b/src/dtagent/plugins/active_queries.config/bom.yml @@ -13,4 +13,4 @@ delivers: references: - name: INFORMATION_SCHEMA.QUERY_HISTORY type: function - privileges: USAGE \ No newline at end of file + privileges: USAGE diff --git a/src/dtagent/plugins/active_queries.config/instruments-def.yml b/src/dtagent/plugins/active_queries.config/instruments-def.yml index 8127b850..0b5d7d0d 100644 --- a/src/dtagent/plugins/active_queries.config/instruments-def.yml +++ b/src/dtagent/plugins/active_queries.config/instruments-def.yml @@ -16,113 +16,110 @@ # * Catalog of instrumentation known to Dynatrace Snowflake Observability Agent - active queries plugin attributes: - db.operation.name: - __example: SELECT - __description: | - The type of operation performed by the query, such as: - - SELECT, - - INSERT, - - UPDATE. - db.query.text: - __example: SELECT * FROM sales_data - __description: The text of the SQL query. - session.id: - __example: "123456789" - __description: - The unique identifier for the session in which the query was - executed. - snowflake.error.code: - __example: "1001" - __description: The error code if the query failed. - snowflake.error.message: - __example: Syntax error in SQL statement - __description: The error message if the query failed. - snowflake.query.hash: - __example: hash_abcdef - __description: The hash value of the query text. - snowflake.query.hash_version: - __example: "1" - __description: The version of the query hash logic. - snowflake.query.id: - __example: b1bbaa7f-8144-4e50-947a-b7e9bf7d62d5 - __description: The unique identifier for the query. - snowflake.query.parametrized_hash: - __example: param_hash_abcdef - __description: The hash value of the parameterized query text. - snowflake.query.parametrized_hash_version: - __example: "1" - __description: The version of the parameterized query hash logic. - snowflake.query.tag: - __example: daily_report - __description: The tag associated with the query, if any. - snowflake.schema.name: - __example: public - __description: The name of the schema in which the query was executed. - snowflake.warehouse.type: - __example: STANDARD - __description: The type of warehouse used to execute the query. + db.operation.name: + __example: SELECT + __description: | + The type of operation performed by the query, such as: + - SELECT, + - INSERT, + - UPDATE. + db.query.text: + __example: SELECT * FROM sales_data + __description: The text of the SQL query. + session.id: + __example: "123456789" + __description: The unique identifier for the session in which the query was executed. + snowflake.error.code: + __example: "1001" + __description: The error code if the query failed. + snowflake.error.message: + __example: Syntax error in SQL statement + __description: The error message if the query failed. + snowflake.query.hash: + __example: hash_abcdef + __description: The hash value of the query text. + snowflake.query.hash_version: + __example: "1" + __description: The version of the query hash logic. + snowflake.query.id: + __example: b1bbaa7f-8144-4e50-947a-b7e9bf7d62d5 + __description: The unique identifier for the query. + snowflake.query.parametrized_hash: + __example: param_hash_abcdef + __description: The hash value of the parameterized query text. + snowflake.query.parametrized_hash_version: + __example: "1" + __description: The version of the parameterized query hash logic. + snowflake.query.tag: + __example: daily_report + __description: The tag associated with the query, if any. + snowflake.schema.name: + __example: public + __description: The name of the schema in which the query was executed. + snowflake.warehouse.type: + __example: STANDARD + __description: The type of warehouse used to execute the query. dimensions: - db.namespace: - __example: analytics_db - __description: The name of the database in which the query was executed. - db.user: - __example: john_doe - __description: The name of the user who executed the query. - snowflake.query.execution_status: - __example: FAILED_WITH_ERROR - __description: | - The execution status of the query, such as: - - RESUMING_WAREHOUSE, - - RUNNING, - - QUEUED, - - BLOCKED, - - SUCCESS, - - FAILED_WITH_ERROR, - - FAILED_WITH_INCIDENT. - snowflake.role.name: - __example: analyst_role - __description: The role that was active in the session at the time of the query. - snowflake.warehouse.name: - __example: compute_wh - __description: The name of the warehouse used to execute the query. + db.namespace: + __example: analytics_db + __description: The name of the database in which the query was executed. + db.user: + __example: john_doe + __description: The name of the user who executed the query. + snowflake.query.execution_status: + __example: FAILED_WITH_ERROR + __description: | + The execution status of the query, such as: + - RESUMING_WAREHOUSE, + - RUNNING, + - QUEUED, + - BLOCKED, + - SUCCESS, + - FAILED_WITH_ERROR, + - FAILED_WITH_INCIDENT. + snowflake.role.name: + __example: analyst_role + __description: The role that was active in the session at the time of the query. + snowflake.warehouse.name: + __example: compute_wh + __description: The name of the warehouse used to execute the query. # * Metric definitions -# * KEY - will be matched against METRICS object with measurements prepared for sending -# * VALUE[__description] - __description of the metrics - in the future we should rather update semantic dictionary instead of pushing it constantly -# * VALUE[unit] - the unit of the metric +# * KEY - will be matched against METRICS object with measurements prepared for sending +# * VALUE[__description] - __description of the metrics - +# in the future we should rather update semantic dictionary instead of pushing it constantly +# * VALUE[unit] - the unit of the metric metrics: - snowflake.time.compilation: - __example: "5000" - __description: | - The total compilation time of the currently running query. - displayName: Query Compilation Time - unit: ms - snowflake.time.running: - __example: "120000" - __description: | - The total running time of the currently running query. - displayName: Query Running Time - unit: ms - snowflake.time.execution: - __example: "100000" - __description: Execution time (in milliseconds) - displayName: Execution Time - unit: ms - snowflake.time.total_elapsed: - __example: "120000" - __description: Elapsed time (in milliseconds). - displayName: Total Elapsed Time - unit: ms - snowflake.data.written_to_result: - __example: "1048576" - __description: Number of bytes written to a result object. - displayName: Bytes Written to Result - unit: bytes - snowflake.rows.written_to_result: - __example: "1" - __description: - Number of rows written to a result object. For CREATE TABLE AS - SELECT (CTAS) and all DML operations, this result is 1;. - displayName: Rows Written to Result - unit: rows + snowflake.time.compilation: + __example: "5000" + __description: | + The total compilation time of the currently running query. + displayName: Query Compilation Time + unit: ms + snowflake.time.running: + __example: "120000" + __description: | + The total running time of the currently running query. + displayName: Query Running Time + unit: ms + snowflake.time.execution: + __example: "100000" + __description: Execution time (in milliseconds) + displayName: Execution Time + unit: ms + snowflake.time.total_elapsed: + __example: "120000" + __description: Elapsed time (in milliseconds). + displayName: Total Elapsed Time + unit: ms + snowflake.data.written_to_result: + __example: "1048576" + __description: Number of bytes written to a result object. + displayName: Bytes Written to Result + unit: bytes + snowflake.rows.written_to_result: + __example: "1" + __description: Number of rows written to a result object. For CREATE TABLE AS SELECT (CTAS) and all DML operations, this result is 1;. + displayName: Rows Written to Result + unit: rows diff --git a/src/dtagent/plugins/active_queries.py b/src/dtagent/plugins/active_queries.py index c1f28054..cf9d001a 100644 --- a/src/dtagent/plugins/active_queries.py +++ b/src/dtagent/plugins/active_queries.py @@ -26,9 +26,9 @@ # SOFTWARE. # # - from typing import Tuple, Dict from dtagent.plugins import Plugin +from dtagent.context import RUN_PLUGIN_KEY, RUN_RESULTS_KEY, RUN_ID_KEY # COMPILE_REMOVE ##endregion COMPILE_REMOVE @@ -40,19 +40,29 @@ class ActiveQueriesPlugin(Plugin): Active queries plugin class. """ - def process(self, run_proc: bool = True) -> Dict[str, Dict[str, int]]: + def process(self, run_id: str, run_proc: bool = True) -> Dict[str, Dict[str, int]]: """ Processes the measures on active queries + Args: + run_id (str): unique run identifier + run_proc (bool): indicator whether processing should be logged as completed + Returns: Dict[str,int]: A dictionary with counts of processed telemetry data. Example: { - "entries": entries_cnt, - "log_lines": logs_cnt, - "metrics": metrics_cnt, - "events": events_cnt + "dsoa.run.results": { + "active_queries": + { + "entries": entries_cnt, + "log_lines": logs_cnt, + "metrics": metrics_cnt, + "events": events_cnt + } + }, + "dsoa.run.id": "uuid_string" } """ t_active_queries = "SELECT * FROM TABLE(DTAGENT_DB.APP.F_ACTIVE_QUERIES_INSTRUMENTED())" @@ -60,12 +70,19 @@ def process(self, run_proc: bool = True) -> Dict[str, Dict[str, int]]: entries_cnt, logs_cnt, metrics_cnt, events_cnt = self._log_entries( lambda: self._get_table_rows(t_active_queries), "active_queries", + run_uuid=run_id, report_timestamp_events=False, report_metrics=True, log_completion=run_proc, ) - return {"active_queries": {"entries": entries_cnt, "log_lines": logs_cnt, "metrics": metrics_cnt, "events": events_cnt}} + return { + RUN_PLUGIN_KEY: "active_queries", + RUN_RESULTS_KEY: { + "active_queries": {"entries": entries_cnt, "log_lines": logs_cnt, "metrics": metrics_cnt, "events": events_cnt} + }, + RUN_ID_KEY: run_id, + } ##endregion diff --git a/src/dtagent/plugins/budgets.config/instruments-def.yml b/src/dtagent/plugins/budgets.config/instruments-def.yml index 675fa055..c59ecb96 100644 --- a/src/dtagent/plugins/budgets.config/instruments-def.yml +++ b/src/dtagent/plugins/budgets.config/instruments-def.yml @@ -15,64 +15,58 @@ # * # Catalog of instrumentation known to Dynatrace Snowflake Observability Agent - budgets plugin attributes: - snowflake.budget.owner: - __example: budget_admin - __description: - The owner of the budget, typically the user or role responsible - for managing the budget. - snowflake.budget.owner.role_type: - __example: ACCOUNTADMIN - __description: - The type of role assigned to the budget owner, indicating their - level of access and responsibilities. - snowflake.budget.resource: - __example: '[ "database1", "warehouse1" ]' - __description: - The resources linked to the budget, such as databases, warehouses, - or other Snowflake objects that the budget monitors. + snowflake.budget.owner: + __example: budget_admin + __description: The owner of the budget, typically the user or role responsible for managing the budget. + snowflake.budget.owner.role_type: + __example: ACCOUNTADMIN + __description: The type of role assigned to the budget owner, indicating their level of access and responsibilities. + snowflake.budget.resource: + __example: '[ "database1", "warehouse1" ]' + __description: The resources linked to the budget, such as databases, warehouses, or other Snowflake objects that the budget monitors. dimensions: - db.namespace: - __example: analytics_db - __description: - The name of the database that was specified in the context of - the query at compilation. - snowflake.budget.name: - __example: monthly_budget - __description: Name of the budget. - snowflake.schema.name: - __example: public - __description: Schema that was specified in the context of the query at compilation. - snowflake.service.type: - __example: WAREHOUSE_METERING - __description: | - Type of service that is consuming credits, which can be one - of the following: - - AUTO_CLUSTERING, - - HYBRID_TABLE_REQUESTS, - - MATERIALIZED_VIEW, - - PIPE, - - QUERY_ACCELERATION, - - SEARCH_OPTIMIZATION, - - SERVERLESS_ALERTS, - - SERVERLESS_TASK, - - SNOWPIPE_STREAMING, - - WAREHOUSE_METERING, - - WAREHOUSE_METERING_READER + db.namespace: + __example: analytics_db + __description: The name of the database that was specified in the context of the query at compilation. + snowflake.budget.name: + __example: monthly_budget + __description: Name of the budget. + snowflake.schema.name: + __example: public + __description: Schema that was specified in the context of the query at compilation. + snowflake.service.type: + __example: WAREHOUSE_METERING + __description: | + Type of service that is consuming credits, which can be one + of the following: + - AUTO_CLUSTERING, + - HYBRID_TABLE_REQUESTS, + - MATERIALIZED_VIEW, + - PIPE, + - QUERY_ACCELERATION, + - SEARCH_OPTIMIZATION, + - SERVERLESS_ALERTS, + - SERVERLESS_TASK, + - SNOWPIPE_STREAMING, + - WAREHOUSE_METERING, + - WAREHOUSE_METERING_READER event_timestamps: - snowflake.budget.created_on: - __example: "2024-11-30 23:59:59.999" - __description: The timestamp when the budget was created. - snowflake.event.trigger: - __example: "snowflake.budget.created_on" - __description: Additionally to sending logs, each entry in `EVENT_TIMESTAMPS` is sent as event with key set to `snowflake.event.trigger`, value to key from `EVENT_TIMESTAMPS` and `timestamp` set to the key value. + snowflake.budget.created_on: + __example: "2024-11-30 23:59:59.999" + __description: The timestamp when the budget was created. + snowflake.event.trigger: + __example: "snowflake.budget.created_on" + __description: + Additionally to sending logs, each entry in `EVENT_TIMESTAMPS` is sent as event with key set to `snowflake.event.trigger`, value to + key from `EVENT_TIMESTAMPS` and `timestamp` set to the key value. metrics: - snowflake.credits.limit: - __example: "100" - __description: The number of credits set as the spending limit for the budget. - displayName: Budget Spending Limit - unit: credits - snowflake.credits.spent: - __example: "75" - __description: Number of credits used. - displayName: Credits Spent - unit: credits + snowflake.credits.limit: + __example: "100" + __description: The number of credits set as the spending limit for the budget. + displayName: Budget Spending Limit + unit: credits + snowflake.credits.spent: + __example: "75" + __description: Number of credits used. + displayName: Credits Spent + unit: credits diff --git a/src/dtagent/plugins/budgets.py b/src/dtagent/plugins/budgets.py index 3e77c58d..4f4b74a6 100644 --- a/src/dtagent/plugins/budgets.py +++ b/src/dtagent/plugins/budgets.py @@ -27,10 +27,10 @@ # # -import uuid from typing import Tuple, Dict from snowflake.snowpark.functions import current_timestamp from dtagent.plugins import Plugin +from dtagent.context import RUN_PLUGIN_KEY, RUN_RESULTS_KEY, RUN_ID_KEY # COMPILE_REMOVE ##endregion COMPILE_REMOVE @@ -41,27 +41,37 @@ class BudgetsPlugin(Plugin): Budgets plugin class. """ - def process(self, run_proc: bool = True) -> Dict[str, Dict[str, int]]: + def process(self, run_id: str, run_proc: bool = True) -> Dict[str, Dict[str, int]]: """ Processes data for budgets plugin. + + Args: + run_id (str): unique run identifier + run_proc (bool): indicator whether processing should be logged as completed + Returns: Dict[str,int]: A dictionary with counts of processed telemetry data. Example: - { - "budgets": { - "entries": budgets_cnt, - "log_lines": logs_budgets_cnt, - "metrics": budgets_metrics_cnt, - "events": budgets_events_cnt, - }, - "spendings": { - "entries": spendings_cnt, - "log_lines": logs_spendings_cnt, - "metrics": spending_metrics_cnt, - "events": spending_events_cnt, + { + "dsoa.run.results": { + "budgets": + { + "entries": budgets_cnt, + "log_lines": logs_budgets_cnt, + "metrics": budgets_metrics_cnt, + "events": budgets_events_cnt, + }, + "spendings": + { + "entries": spendings_cnt, + "log_lines": logs_spendings_cnt, + "metrics": spending_metrics_cnt, + "events": spending_events_cnt, + }, }, - } + "dsoa.run.id": "uuid_string" + } """ budgets_cnt = 0 @@ -74,8 +84,6 @@ def process(self, run_proc: bool = True) -> Dict[str, Dict[str, int]]: # this procedure ensures that the budgets and spendings tables are up to date self._session.call(p_refresh_budgets) - run_id = str(uuid.uuid4().hex) - budgets_cnt, logs_budgets_cnt, budgets_metrics_cnt, budgets_events_cnt = self._log_entries( lambda: self._get_table_rows(t_get_budgets), "budgets", @@ -108,11 +116,6 @@ def process(self, run_proc: bool = True) -> Dict[str, Dict[str, int]]: } if run_proc: - self._report_execution( - "budgets", - current_timestamp(), - None, - results_dict, - ) - - return results_dict + self._report_execution("budgets", current_timestamp(), None, results_dict, run_id=run_id) + + return {RUN_PLUGIN_KEY: "budgets", RUN_RESULTS_KEY: results_dict, RUN_ID_KEY: run_id} diff --git a/src/dtagent/plugins/budgets.sql/040_p_get_budgets.sql b/src/dtagent/plugins/budgets.sql/040_p_get_budgets.sql index f5b8d4e5..4a988563 100644 --- a/src/dtagent/plugins/budgets.sql/040_p_get_budgets.sql +++ b/src/dtagent/plugins/budgets.sql/040_p_get_budgets.sql @@ -53,8 +53,7 @@ execute as owner as $$ DECLARE - q_get_budgets TEXT DEFAULT 'show SNOWFLAKE.CORE.BUDGET;'; - q_pop_budgets TEXT DEFAULT 'insert into DTAGENT_DB.APP.TMP_BUDGETS select * from table(result_scan(last_query_id()));'; + q_get_budgets TEXT DEFAULT 'show SNOWFLAKE.CORE.BUDGET ->> insert into DTAGENT_DB.APP.TMP_BUDGETS select * from $1;'; tr_budgets TEXT DEFAULT 'truncate table DTAGENT_DB.APP.TMP_BUDGETS;'; tr_linked_resources TEXT DEFAULT 'truncate table DTAGENT_DB.APP.TMP_BUDGETS_RESOURCES;'; @@ -75,7 +74,6 @@ BEGIN EXECUTE IMMEDIATE :tr_spendings; EXECUTE IMMEDIATE :q_get_budgets; - EXECUTE IMMEDIATE :q_pop_budgets; FOR budget IN c_budgets DO budget_name := budget.name; diff --git a/src/dtagent/plugins/data_schemas.config/bom.yml b/src/dtagent/plugins/data_schemas.config/bom.yml index 650387ad..e14b4e78 100644 --- a/src/dtagent/plugins/data_schemas.config/bom.yml +++ b/src/dtagent/plugins/data_schemas.config/bom.yml @@ -9,4 +9,4 @@ delivers: references: - name: SNOWFLAKE.ACCOUNT_USAGE.ACCESS_HISTORY type: view - privileges: SELECT \ No newline at end of file + privileges: SELECT diff --git a/src/dtagent/plugins/data_schemas.config/instruments-def.yml b/src/dtagent/plugins/data_schemas.config/instruments-def.yml index d96e88a7..d851282b 100644 --- a/src/dtagent/plugins/data_schemas.config/instruments-def.yml +++ b/src/dtagent/plugins/data_schemas.config/instruments-def.yml @@ -15,47 +15,47 @@ # * # Catalog of instrumentation known to Dynatrace Snowflake Observability Agent - data_schemas plugin attributes: - snowflake.query.id: - __example: 01b30d58-0604-6e1c-0040-e003029c1322 - __description: An internal, system-generated identifier for the SQL statement. - db.user: - __example: SYSTEM - __description: The user who issued the query. - snowflake.query.parent_id: - __example: 01b2fd01-0604-6864-0040-e003029abda2 - __description: The query ID of the parent job or NULL if the job does not have a parent. - snowflake.query.root_id: - __example: 01b2fd00-0604-6864-0040-e003029abd82 - __description: The query ID of the top most job in the chain or NULL if the job does not have a parent. - snowflake.object.ddl.modified: - __example: '{ "DTAGENT_DB.APP.TMP_RECENT_QUERIES": { - "objectColumns": "HISTOGRAM_METRICS, COUNTER_METRICS, START_TIME, STATUS_CODE, SESSION_ID, QUERY_ID, DIMENSIONS, END_TIME, NAME, ATTRIBUTES, PARENT_QUERY_ID", - "objectDomain": "Table" } }' - __description: A JSON array that specifies the objects that were associated with a write operation in the query. - snowflake.object.type: - __example: "Table" - __description: | - The domain of the object defined or modified by the DDL operation, which includes all objects that can be tagged and: - - MASKING POLICY, - - ROW ACCESS POLICY, - - TAG. - snowflake.object.id: - __example: 747545 - __description: An identifier for the object, which is unique within a given account and domain. - snowflake.object.name: - __example: "DTAGENT_DB.APP.TMP_RECENT_QUERIES" - __description: The fully qualified name of the object defined or modified by the DDL operation. - snowflake.object.ddl.operation: - __example: "REPLACE" - __description: | - The SQL keyword that specifies the operation on the table, view, or column: - - ALTER, - - CREATE, - - DROP, - - REPLACE, - - UNDROP. - snowflake.object.ddl.properties: - __example: '{"creationMode": "CREATE", "columns": {"ADD": ["ATTRIBUTE","JOB_ID"]}}' - __description: | - A JSON array that specifies the object or column properties when you create, modify, drop, or undrop the object or column. - There are two types of properties: atomic and compound. + snowflake.query.id: + __example: 01b30d58-0604-6e1c-0040-e003029c1322 + __description: An internal, system-generated identifier for the SQL statement. + db.user: + __example: SYSTEM + __description: The user who issued the query. + snowflake.query.parent_id: + __example: 01b2fd01-0604-6864-0040-e003029abda2 + __description: The query ID of the parent job or NULL if the job does not have a parent. + snowflake.query.root_id: + __example: 01b2fd00-0604-6864-0040-e003029abd82 + __description: The query ID of the top most job in the chain or NULL if the job does not have a parent. + snowflake.object.ddl.modified: + __example: + '{ "DTAGENT_DB.APP.TMP_RECENT_QUERIES": { "objectColumns": "HISTOGRAM_METRICS, COUNTER_METRICS, START_TIME, STATUS_CODE, SESSION_ID, + QUERY_ID, DIMENSIONS, END_TIME, NAME, ATTRIBUTES, PARENT_QUERY_ID", "objectDomain": "Table" } }' + __description: A JSON array that specifies the objects that were associated with a write operation in the query. + snowflake.object.type: + __example: "Table" + __description: | + The domain of the object defined or modified by the DDL operation, which includes all objects that can be tagged and: + - MASKING POLICY, + - ROW ACCESS POLICY, + - TAG. + snowflake.object.id: + __example: 747545 + __description: An identifier for the object, which is unique within a given account and domain. + snowflake.object.name: + __example: "DTAGENT_DB.APP.TMP_RECENT_QUERIES" + __description: The fully qualified name of the object defined or modified by the DDL operation. + snowflake.object.ddl.operation: + __example: "REPLACE" + __description: | + The SQL keyword that specifies the operation on the table, view, or column: + - ALTER, + - CREATE, + - DROP, + - REPLACE, + - UNDROP. + snowflake.object.ddl.properties: + __example: '{"creationMode": "CREATE", "columns": {"ADD": ["ATTRIBUTE","JOB_ID"]}}' + __description: | + A JSON array that specifies the object or column properties when you create, modify, drop, or undrop the object or column. + There are two types of properties: atomic and compound. diff --git a/src/dtagent/plugins/data_schemas.py b/src/dtagent/plugins/data_schemas.py index f4a90ee9..0a2f612f 100644 --- a/src/dtagent/plugins/data_schemas.py +++ b/src/dtagent/plugins/data_schemas.py @@ -31,6 +31,7 @@ from dtagent.plugins import Plugin from dtagent.otel.events import EventType from dtagent.util import _from_json, _pack_values_to_json_strings +from dtagent.context import RUN_PLUGIN_KEY, RUN_RESULTS_KEY, RUN_ID_KEY # COMPILE_REMOVE ##endregion COMPILE_REMOVE @@ -98,26 +99,35 @@ def _report_all_entries_as_events( context=context, ) - def process(self, run_proc: bool = True) -> Dict[str, Dict[str, int]]: + def process(self, run_id: str, run_proc: bool = True) -> Dict[str, Dict[str, int]]: """ Processes data for data schemas plugin. + + Args: + run_id (str): unique run identifier + run_proc (bool): indicator whether processing should be logged as completed + Returns: Dict[str,Dict[str,int]]: A dictionary with telemetry counts for data schemas. Example: { + "dsoa.run.results": { "data_schemas": { "entries": entries_cnt, "log_lines": logs_cnt, "metrics": metrics_cnt, "events": events_cnt, } + }, + RUN_ID_KEY: run_id, } """ entries_cnt, logs_cnt, metrics_cnt, events_cnt = self._log_entries( f_entry_generator=lambda: self._get_table_rows("APP.V_DATA_SCHEMAS"), context_name="data_schemas", + run_uuid=run_id, report_logs=False, report_timestamp_events=False, report_metrics=False, @@ -129,10 +139,14 @@ def process(self, run_proc: bool = True) -> Dict[str, Dict[str, int]]: ) return { - "data_schemas": { - "entries": entries_cnt, - "log_lines": logs_cnt, - "metrics": metrics_cnt, - "events": events_cnt, - } + RUN_PLUGIN_KEY: "data_schemas", + RUN_RESULTS_KEY: { + "data_schemas": { + "entries": entries_cnt, + "log_lines": logs_cnt, + "events": events_cnt, + "metrics": metrics_cnt, + }, + }, + RUN_ID_KEY: run_id, } diff --git a/src/dtagent/plugins/data_volume.config/bom.yml b/src/dtagent/plugins/data_volume.config/bom.yml index ff1e1bfe..66a8d3e6 100644 --- a/src/dtagent/plugins/data_volume.config/bom.yml +++ b/src/dtagent/plugins/data_volume.config/bom.yml @@ -9,4 +9,4 @@ delivers: references: - name: SNOWFLAKE.ACCOUNT_USAGE.TABLES type: view - privileges: SELECT \ No newline at end of file + privileges: SELECT diff --git a/src/dtagent/plugins/data_volume.config/instruments-def.yml b/src/dtagent/plugins/data_volume.config/instruments-def.yml index 5de761c8..87f495cb 100644 --- a/src/dtagent/plugins/data_volume.config/instruments-def.yml +++ b/src/dtagent/plugins/data_volume.config/instruments-def.yml @@ -18,68 +18,63 @@ # * dimensions: - db.collection.name: - __example: analytics_db.public.sales_data - __description: - The full name of the table, including the catalog, schema, and - table name. - db.namespace: - __example: analytics_db - __description: The name of the database that contains the table. - snowflake.table.type: - __example: BASE TABLE - __description: | - The type of the table, such as: - - BASE TABLE, - - TEMPORARY TABLE, - - EXTERNAL TABLE. + db.collection.name: + __example: analytics_db.public.sales_data + __description: The full name of the table, including the catalog, schema, and table name. + db.namespace: + __example: analytics_db + __description: The name of the database that contains the table. + snowflake.table.type: + __example: BASE TABLE + __description: | + The type of the table, such as: + - BASE TABLE, + - TEMPORARY TABLE, + - EXTERNAL TABLE. # * Metric definitions -# * KEY - will be matched against METRICS object with measurements prepared for sending -# * VALUE[__description] - __description of the metrics - in the future we should rather update semantic dictionary instead of pushing it constantly -# * VALUE[unit] - the unit of the metric +# * KEY - will be matched against METRICS object with measurements prepared for sending +# * VALUE[__description] - __description of the metrics - +# in the future we should rather update semantic dictionary instead of pushing it constantly +# * VALUE[unit] - the unit of the metric metrics: - snowflake.data.rows: - __example: "1000000" - __description: Sum of all rows in all objects in this scope. - displayName: Row Count - unit: rows - snowflake.data.size: - __example: "1073741824" - __description: Total size (in bytes) of all objects in this scope. - displayName: Table Size in Bytes - unit: bytes - snowflake.table.time_since.last_ddl: - __example: "2880" - __description: - Time (in minutes) since last time given objects structure was - altered. - displayName: Time Since Last DDL - unit: min - snowflake.table.time_since.last_update: - __example: "1440" - __description: - Time (in minutes) since last time content of given objects was - updated. - displayName: Time Since Last Update - unit: min + snowflake.data.rows: + __example: "1000000" + __description: Sum of all rows in all objects in this scope. + displayName: Row Count + unit: rows + snowflake.data.size: + __example: "1073741824" + __description: Total size (in bytes) of all objects in this scope. + displayName: Table Size in Bytes + unit: bytes + snowflake.table.time_since.last_ddl: + __example: "2880" + __description: Time (in minutes) since last time given objects structure was altered. + displayName: Time Since Last DDL + unit: min + snowflake.table.time_since.last_update: + __example: "1440" + __description: Time (in minutes) since last time content of given objects was updated. + displayName: Time Since Last Update + unit: min event_timestamps: - snowflake.table.ddl: - __example: "2024-11-01 12:00:00.000" - __description: | - Timestamp of the last DDL operation performed on the table or - view. All supported table/view DDL operations update this field: - - CREATE, - - ALTER, - - DROP, - - UNDROP - snowflake.table.update: - __example: "2024-11-10 16:45:00.000" - __description: - Date and time the object was last altered by a DML, DDL, or background - metadata operation. - snowflake.event.trigger: - __example: "snowflake.table.update" - __description: Additionally to sending logs, each entry in `EVENT_TIMESTAMPS` is sent as event with key set to `snowflake.event.trigger`, value to key from `EVENT_TIMESTAMPS` and `timestamp` set to the key value. + snowflake.table.ddl: + __example: "2024-11-01 12:00:00.000" + __description: | + Timestamp of the last DDL operation performed on the table or + view. All supported table/view DDL operations update this field: + - CREATE, + - ALTER, + - DROP, + - UNDROP + snowflake.table.update: + __example: "2024-11-10 16:45:00.000" + __description: Date and time the object was last altered by a DML, DDL, or background metadata operation. + snowflake.event.trigger: + __example: "snowflake.table.update" + __description: + Additionally to sending logs, each entry in `EVENT_TIMESTAMPS` is sent as event with key set to `snowflake.event.trigger`, value to + key from `EVENT_TIMESTAMPS` and `timestamp` set to the key value. diff --git a/src/dtagent/plugins/data_volume.py b/src/dtagent/plugins/data_volume.py index 09e8f4fb..7d87acf3 100644 --- a/src/dtagent/plugins/data_volume.py +++ b/src/dtagent/plugins/data_volume.py @@ -26,10 +26,10 @@ # SOFTWARE. # # - from snowflake.snowpark.functions import current_timestamp from dtagent.plugins import Plugin from typing import Dict +from dtagent.context import RUN_PLUGIN_KEY, RUN_RESULTS_KEY, RUN_ID_KEY # COMPILE_REMOVE ##endregion COMPILE_REMOVE @@ -41,47 +41,51 @@ class DataVolumePlugin(Plugin): Data volume plugin class. """ - def process(self, run_proc: bool = True) -> Dict[str, Dict[str, int]]: + def process(self, run_id: str, run_proc: bool = True) -> Dict[str, Dict[str, int]]: """ Processes the measures on data volume + Args: + run_id (str): unique run identifier + run_proc (bool): indicator whether processing should be logged as completed + Returns: Dict[str,int]: A dictionary with telemetry counts for data volume. Example: { + "dsoa.run.results": { "data_volume": { "entries": entries_cnt, "log_lines": logs_cnt, "metrics": metrics_cnt, "events": events_cnt, } + }, + "dsoa.run.id": "uuid_string" } """ - entries_cnt, logs_cnt, metrics_cnt, events_cnt = self._log_entries( f_entry_generator=lambda: self._get_table_rows("APP.V_DATA_VOLUME"), context_name="data_volume", + run_uuid=run_id, report_logs=False, log_completion=False, ) - processed_tables = { - "data_volume": { - "entries": entries_cnt, - "log_lines": logs_cnt, - "metrics": metrics_cnt, - "events": events_cnt, - } + results_dict = { + "entries": entries_cnt, + "log_lines": logs_cnt, + "metrics": metrics_cnt, + "events": events_cnt, } if run_proc: - self._report_execution( - "data_volume", - current_timestamp(), - None, - processed_tables, - ) + self._report_execution("data_volume", current_timestamp(), None, results_dict, run_id=run_id) - return processed_tables + return { + RUN_PLUGIN_KEY: "data_volume", + RUN_RESULTS_KEY: {"data_volume": results_dict}, + RUN_ID_KEY: run_id, + } ##endregion diff --git a/src/dtagent/plugins/dynamic_tables.config/instruments-def.yml b/src/dtagent/plugins/dynamic_tables.config/instruments-def.yml index f0fd2594..6de164bc 100644 --- a/src/dtagent/plugins/dynamic_tables.config/instruments-def.yml +++ b/src/dtagent/plugins/dynamic_tables.config/instruments-def.yml @@ -16,329 +16,307 @@ # * Catalog of instrumentation known to Dynatrace Snowflake Observability Agent - dynamic tables plugin # attributes: - db.query.text: - __context_names: - - dynamic_table_graph_history - __example: - SELECT A.EMP_ID,A.EMP_NAME,A.EMP_ADDRESS, B.SKILL_ID,B.SKILL_NAME,B.SKILL_LEVEL - FROM EMPLOYEE A, EMPLOYEE_SKILL B WHERE A.EMP_ID=B.EMP_ID ORDER BY B.SKILL_ID - ; - __description: The SELECT statement for this dynamic table. - snowflake.query.id: - __context_names: - - dynamic_tables - - dynamic_table_refresh_history - __example: 01b899f1-0712-45a6-0040-e00303977b8e - __description: - If present, this represents the query ID of the refresh job that - produced the results for the dynamic table. - snowflake.table.dynamic.graph.alter_trigger: - __context_names: - - dynamic_table_graph_history - __example: '[ "CREATE_DYNAMIC_TABLE" ]' - __description: | - Describes why a new entry is created in the DYNAMIC_TABLE_GRAPH_HISTORY - function. Can be one of the following: - - NONE (backwards-compatible), - - CREATE_DYNAMIC_TABLE, - - ALTER_TARGET_LAG, - - SUSPEND, RESUME, - - REPLICATION_REFRESH, - - ALTER_WAREHOUSE. - snowflake.table.dynamic.graph.inputs: - __context_names: - - dynamic_table_graph_history - __example: - '[ { "kind": "TABLE", "name": "DYNAMIC_TABLE_DB.DYNAMIC_TABLE_SCH.EMPLOYEE" - }, { "kind": "TABLE", "name": "DYNAMIC_TABLE_DB.DYNAMIC_TABLE_SCH.EMPLOYEE_SKILL" - } ]' - __description: - Each OBJECT represents a table, view, or dynamic table that serves - as the input to this dynamic table. - snowflake.table.dynamic.graph.valid_from: - __context_names: - - dynamic_table_refresh_history - - dynamic_table_graph_history - __example: "2024-11-20 19:53:47.448 Z" - __description: - Encodes the VALID_FROM timestamp of the DYNAMIC_TABLE_GRAPH_HISTORY - table function when the refresh occurred. - snowflake.table.dynamic.graph.valid_to: - __context_names: - - dynamic_table_graph_history - __example: "" - __description: - If present, the description of the dynamic table is valid up - to this time. If null, the description is still accurate. - snowflake.table.dynamic.lag.target.type: - __context_names: - - dynamic_tables - - dynamic_table_graph_history - __example: USER_DEFINED - __description: The type of target lag. - snowflake.table.dynamic.latest.code: - __context_names: - - dynamic_tables - __example: SUCCESS - __description: - Code representing the current state of the refresh. If the LAST_COMPLETED_REFRESH_STATE - is FAILED, this column shows the error code associated with the failure. - snowflake.table.dynamic.latest.data_timestamp: - __context_names: - - dynamic_tables - __example: "2024-11-22 12:55:29.695 Z" - __description: Data timestamp of the last successful refresh. - snowflake.table.dynamic.latest.dependency.data_timestamp: - __context_names: - - dynamic_table_refresh_history - __example: "2024-11-25 06:09:53.695 Z" - __description: Data timestamp of the latest dependency to become available. - snowflake.table.dynamic.latest.dependency.name: - __context_names: - - dynamic_table_refresh_history - __example: DYNAMIC_TABLE_DB.DYNAMIC_TABLE_SCH.EMPLOYEE - __description: Qualified name of the latest dependency to become available. - snowflake.table.dynamic.latest.message: - __context_names: - - dynamic_tables - __example: "" - __description: - Description of the current state of the refresh. If the LAST_COMPLETED_REFRESH_STATE - is FAILED, this column shows the error message associated with the failure. - snowflake.table.dynamic.latest.state: - __context_names: - - dynamic_tables - __example: SUCCEEDED - __description: | - Status of the last terminated refresh for the dynamic table. - Can be one of the following: - - **SUCCEEDED**: Refresh completed successfully, - - **FAILED**: Refresh failed during execution, - - **UPSTREAM_FAILED**: Refresh not performed due to an upstream failed refresh, - - **CANCELLED**: Refresh was canceled before execution. - snowflake.table.dynamic.refresh.action: - __context_names: - - dynamic_table_refresh_history - __example: NO_DATA - __description: | - Describes the type of refresh action performed. One of: - - **NO_DATA**: no new data in base tables. Doesn’t apply to the initial refresh of - newly created dynamic tables whether or not the base tables have data, - - **REINITIALIZE**: base table changed or source table of a cloned - dynamic table was refreshed during clone, - - **FULL**: Full refresh, because - dynamic table contains query elements that are not incremental (see - SHOW DYNAMIC TABLE refresh_mode_reason) or because full refresh was cheaper - than incremental refresh, - - **INCREMENTAL**: normal incremental refresh. - snowflake.table.dynamic.refresh.code: - __context_names: - - dynamic_table_refresh_history - __example: SUCCESS - __description: Code representing the current state of the refresh. - snowflake.table.dynamic.refresh.completion_target: - __context_names: - - dynamic_table_refresh_history - __example: "2024-11-25 06:10:05.695 Z" - __description: - Time by which this refresh should complete to keep lag under - the TARGET_LAG parameter for the dynamic table. - snowflake.table.dynamic.refresh.data_timestamp: - __context_names: - - dynamic_table_refresh_history - __example: "2024-11-25 06:09:53.695 Z" - __description: Transactional timestamp when the refresh was evaluated. - snowflake.table.dynamic.refresh.end: - __context_names: - - dynamic_table_refresh_history - __example: "2024-11-25 06:09:55.308 Z" - __description: Time when the refresh completed. - snowflake.table.dynamic.refresh.message: - __context_names: - - dynamic_table_refresh_history - __example: "" - __description: Description of the current state of the refresh. - snowflake.table.dynamic.refresh.start: - __context_names: - - dynamic_table_refresh_history - __example: "2024-11-25 06:09:54.978 Z" - __description: Time when the refresh job started. - snowflake.table.dynamic.refresh.state: - __context_names: - - dynamic_table_refresh_history - __example: SUCCEEDED - __description: | - Status of the refresh for the dynamic table. The status can be one of the following: - - **SCHEDULED**: refresh scheduled, but not yet executed, - - **EXECUTING**: refresh in progress, - - **SUCCEEDED**: refresh completed successfully, - - **FAILED**: refresh failed during execution, - - **CANCELLED**: refresh was canceled before execution, - - **UPSTREAM_FAILED**: refresh not performed due to an upstream failed refresh. - snowflake.table.dynamic.refresh.trigger: - __context_names: - - dynamic_table_refresh_history - __example: SCHEDULED - __description: | - Describes the trigger for the refresh. One of: - - **SCHEDULED**: normal background refresh to meet target lag or downstream target lag, - - **MANUAL**: user/task used ALTER DYNAMIC TABLE REFRESH, - - **CREATION**: refresh performed during the creation DDL statement, triggered by the creation - of the dynamic table or any consumer dynamic tables. - snowflake.table.dynamic.scheduling.reason.code: - __context_names: - - dynamic_tables - - dynamic_table_graph_history - __example: MAINTENANCE - __description: Optional reason code if the state is not ACTIVE. - snowflake.table.dynamic.scheduling.reason.message: - __context_names: - - dynamic_tables - - dynamic_table_graph_history - __example: Scheduled maintenance - __description: - Text description of the reason the dynamic table is not active. - Only applies if the state is not active. - snowflake.table.dynamic.scheduling.state: - __context_names: - - dynamic_tables - - dynamic_table_graph_history - __example: ACTIVE - __description: Scheduling state of the dynamic table. + db.query.text: + __context_names: + - dynamic_table_graph_history + __example: + SELECT A.EMP_ID,A.EMP_NAME,A.EMP_ADDRESS, B.SKILL_ID,B.SKILL_NAME,B.SKILL_LEVEL FROM EMPLOYEE A, EMPLOYEE_SKILL B WHERE + A.EMP_ID=B.EMP_ID ORDER BY B.SKILL_ID ; + __description: The SELECT statement for this dynamic table. + snowflake.query.id: + __context_names: + - dynamic_tables + - dynamic_table_refresh_history + __example: 01b899f1-0712-45a6-0040-e00303977b8e + __description: If present, this represents the query ID of the refresh job that produced the results for the dynamic table. + snowflake.table.dynamic.graph.alter_trigger: + __context_names: + - dynamic_table_graph_history + __example: '[ "CREATE_DYNAMIC_TABLE" ]' + __description: | + Describes why a new entry is created in the DYNAMIC_TABLE_GRAPH_HISTORY + function. Can be one of the following: + - NONE (backwards-compatible), + - CREATE_DYNAMIC_TABLE, + - ALTER_TARGET_LAG, + - SUSPEND, RESUME, + - REPLICATION_REFRESH, + - ALTER_WAREHOUSE. + snowflake.table.dynamic.graph.inputs: + __context_names: + - dynamic_table_graph_history + __example: + '[ { "kind": "TABLE", "name": "DYNAMIC_TABLE_DB.DYNAMIC_TABLE_SCH.EMPLOYEE" }, { "kind": "TABLE", "name": + "DYNAMIC_TABLE_DB.DYNAMIC_TABLE_SCH.EMPLOYEE_SKILL" } ]' + __description: Each OBJECT represents a table, view, or dynamic table that serves as the input to this dynamic table. + snowflake.table.dynamic.graph.valid_from: + __context_names: + - dynamic_table_refresh_history + - dynamic_table_graph_history + __example: "2024-11-20 19:53:47.448 Z" + __description: Encodes the VALID_FROM timestamp of the DYNAMIC_TABLE_GRAPH_HISTORY table function when the refresh occurred. + snowflake.table.dynamic.graph.valid_to: + __context_names: + - dynamic_table_graph_history + __example: "" + __description: If present, the description of the dynamic table is valid up to this time. If null, the description is still accurate. + snowflake.table.dynamic.lag.target.type: + __context_names: + - dynamic_tables + - dynamic_table_graph_history + __example: USER_DEFINED + __description: The type of target lag. + snowflake.table.dynamic.latest.code: + __context_names: + - dynamic_tables + __example: SUCCESS + __description: + Code representing the current state of the refresh. If the LAST_COMPLETED_REFRESH_STATE is FAILED, this column shows the error code + associated with the failure. + snowflake.table.dynamic.latest.data_timestamp: + __context_names: + - dynamic_tables + __example: "2024-11-22 12:55:29.695 Z" + __description: Data timestamp of the last successful refresh. + snowflake.table.dynamic.latest.dependency.data_timestamp: + __context_names: + - dynamic_table_refresh_history + __example: "2024-11-25 06:09:53.695 Z" + __description: Data timestamp of the latest dependency to become available. + snowflake.table.dynamic.latest.dependency.name: + __context_names: + - dynamic_table_refresh_history + __example: DYNAMIC_TABLE_DB.DYNAMIC_TABLE_SCH.EMPLOYEE + __description: Qualified name of the latest dependency to become available. + snowflake.table.dynamic.latest.message: + __context_names: + - dynamic_tables + __example: "" + __description: + Description of the current state of the refresh. If the LAST_COMPLETED_REFRESH_STATE is FAILED, this column shows the error message + associated with the failure. + snowflake.table.dynamic.latest.state: + __context_names: + - dynamic_tables + __example: SUCCEEDED + __description: | + Status of the last terminated refresh for the dynamic table. + Can be one of the following: + - **SUCCEEDED**: Refresh completed successfully, + - **FAILED**: Refresh failed during execution, + - **UPSTREAM_FAILED**: Refresh not performed due to an upstream failed refresh, + - **CANCELLED**: Refresh was canceled before execution. + snowflake.table.dynamic.refresh.action: + __context_names: + - dynamic_table_refresh_history + __example: NO_DATA + __description: | + Describes the type of refresh action performed. One of: + - **NO_DATA**: no new data in base tables. Doesn’t apply to the initial refresh of + newly created dynamic tables whether or not the base tables have data, + - **REINITIALIZE**: base table changed or source table of a cloned + dynamic table was refreshed during clone, + - **FULL**: Full refresh, because + dynamic table contains query elements that are not incremental (see + SHOW DYNAMIC TABLE refresh_mode_reason) or because full refresh was cheaper + than incremental refresh, + - **INCREMENTAL**: normal incremental refresh. + snowflake.table.dynamic.refresh.code: + __context_names: + - dynamic_table_refresh_history + __example: SUCCESS + __description: Code representing the current state of the refresh. + snowflake.table.dynamic.refresh.completion_target: + __context_names: + - dynamic_table_refresh_history + __example: "2024-11-25 06:10:05.695 Z" + __description: Time by which this refresh should complete to keep lag under the TARGET_LAG parameter for the dynamic table. + snowflake.table.dynamic.refresh.data_timestamp: + __context_names: + - dynamic_table_refresh_history + __example: "2024-11-25 06:09:53.695 Z" + __description: Transactional timestamp when the refresh was evaluated. + snowflake.table.dynamic.refresh.end: + __context_names: + - dynamic_table_refresh_history + __example: "2024-11-25 06:09:55.308 Z" + __description: Time when the refresh completed. + snowflake.table.dynamic.refresh.message: + __context_names: + - dynamic_table_refresh_history + __example: "" + __description: Description of the current state of the refresh. + snowflake.table.dynamic.refresh.start: + __context_names: + - dynamic_table_refresh_history + __example: "2024-11-25 06:09:54.978 Z" + __description: Time when the refresh job started. + snowflake.table.dynamic.refresh.state: + __context_names: + - dynamic_table_refresh_history + __example: SUCCEEDED + __description: | + Status of the refresh for the dynamic table. The status can be one of the following: + - **SCHEDULED**: refresh scheduled, but not yet executed, + - **EXECUTING**: refresh in progress, + - **SUCCEEDED**: refresh completed successfully, + - **FAILED**: refresh failed during execution, + - **CANCELLED**: refresh was canceled before execution, + - **UPSTREAM_FAILED**: refresh not performed due to an upstream failed refresh. + snowflake.table.dynamic.refresh.trigger: + __context_names: + - dynamic_table_refresh_history + __example: SCHEDULED + __description: | + Describes the trigger for the refresh. One of: + - **SCHEDULED**: normal background refresh to meet target lag or downstream target lag, + - **MANUAL**: user/task used ALTER DYNAMIC TABLE REFRESH, + - **CREATION**: refresh performed during the creation DDL statement, triggered by the creation + of the dynamic table or any consumer dynamic tables. + snowflake.table.dynamic.scheduling.reason.code: + __context_names: + - dynamic_tables + - dynamic_table_graph_history + __example: MAINTENANCE + __description: Optional reason code if the state is not ACTIVE. + snowflake.table.dynamic.scheduling.reason.message: + __context_names: + - dynamic_tables + - dynamic_table_graph_history + __example: Scheduled maintenance + __description: Text description of the reason the dynamic table is not active. Only applies if the state is not active. + snowflake.table.dynamic.scheduling.state: + __context_names: + - dynamic_tables + - dynamic_table_graph_history + __example: ACTIVE + __description: Scheduling state of the dynamic table. dimensions: - db.collection.name: - __context_names: - - dynamic_tables - - dynamic_table_refresh_history - - dynamic_table_graph_history - __example: EMPLOYEE_DET - __description: Name of the dynamic table. - db.namespace: - __context_names: - - dynamic_tables - - dynamic_table_refresh_history - - dynamic_table_graph_history - __example: DYNAMIC_TABLE_DB - __description: The name of the database in which the query was executed. - snowflake.schema.name: - __context_names: - - dynamic_tables - - dynamic_table_refresh_history - - dynamic_table_graph_history - __example: DYNAMIC_TABLE_SCH - __description: Name of the schema that contains the dynamic table. - snowflake.table.full_name: - __context_names: - - dynamic_tables - - dynamic_table_refresh_history - - dynamic_table_graph_history - __example: DYNAMIC_TABLE_DB.DYNAMIC_TABLE_SCH.EMPLOYEE_DET - __description: Fully qualified name of the dynamic table. + db.collection.name: + __context_names: + - dynamic_tables + - dynamic_table_refresh_history + - dynamic_table_graph_history + __example: EMPLOYEE_DET + __description: Name of the dynamic table. + db.namespace: + __context_names: + - dynamic_tables + - dynamic_table_refresh_history + - dynamic_table_graph_history + __example: DYNAMIC_TABLE_DB + __description: The name of the database in which the query was executed. + snowflake.schema.name: + __context_names: + - dynamic_tables + - dynamic_table_refresh_history + - dynamic_table_graph_history + __example: DYNAMIC_TABLE_SCH + __description: Name of the schema that contains the dynamic table. + snowflake.table.full_name: + __context_names: + - dynamic_tables + - dynamic_table_refresh_history + - dynamic_table_graph_history + __example: DYNAMIC_TABLE_DB.DYNAMIC_TABLE_SCH.EMPLOYEE_DET + __description: Fully qualified name of the dynamic table. event_timestamps: - snowflake.event.trigger: - __context_names: - - dynamic_table_refresh_history - - dynamic_table_graph_history - __example: "snowflake.table.dynamic.scheduling.resumed_on" - __description: Additionally to sending logs, each entry in `EVENT_TIMESTAMPS` is sent as event with key set to `snowflake.event.trigger`, value to key from `EVENT_TIMESTAMPS` and `timestamp` set to the key value. - snowflake.table.dynamic.graph.valid_from: - __context_names: - - dynamic_table_refresh_history - - dynamic_table_graph_history - __example: "2024-11-20 19:53:47.448 Z" - __description: The description of the dynamic table is valid after this time. - snowflake.table.dynamic.scheduling.resumed_on: - __context_names: - - dynamic_table_graph_history - __example: "2024-11-25 08:09:53.695 Z" - __description: - Optional timestamp when it was last resumed if dynamic table - is ACTIVE. - snowflake.table.dynamic.scheduling.suspended_on: - __context_names: - - dynamic_table_graph_history - __example: "2024-11-25 06:09:53.695 Z" - __description: Optional timestamp when the dynamic table was suspended. + snowflake.event.trigger: + __context_names: + - dynamic_table_refresh_history + - dynamic_table_graph_history + __example: "snowflake.table.dynamic.scheduling.resumed_on" + __description: + Additionally to sending logs, each entry in `EVENT_TIMESTAMPS` is sent as event with key set to `snowflake.event.trigger`, value to + key from `EVENT_TIMESTAMPS` and `timestamp` set to the key value. + snowflake.table.dynamic.graph.valid_from: + __context_names: + - dynamic_table_refresh_history + - dynamic_table_graph_history + __example: "2024-11-20 19:53:47.448 Z" + __description: The description of the dynamic table is valid after this time. + snowflake.table.dynamic.scheduling.resumed_on: + __context_names: + - dynamic_table_graph_history + __example: "2024-11-25 08:09:53.695 Z" + __description: Optional timestamp when it was last resumed if dynamic table is ACTIVE. + snowflake.table.dynamic.scheduling.suspended_on: + __context_names: + - dynamic_table_graph_history + __example: "2024-11-25 06:09:53.695 Z" + __description: Optional timestamp when the dynamic table was suspended. metrics: - snowflake.partitions.added: - __context_names: - - dynamic_table_refresh_history - __example: "5" - __description: The number of partitions added during the refresh. - displayName: Partitions Added - unit: partitions - snowflake.partitions.removed: - __context_names: - - dynamic_table_refresh_history - __example: "3" - __description: The number of partitions removed during the refresh. - displayName: Partitions Removed - unit: partitions - snowflake.rows.copied: - __context_names: - - dynamic_table_refresh_history - __example: "75" - __description: The number of rows copied during the refresh. - displayName: Rows Copied - unit: rows - snowflake.rows.deleted: - __context_names: - - dynamic_table_refresh_history - __example: "50" - __description: The number of rows deleted during the refresh. - displayName: Rows Deleted - unit: rows - snowflake.rows.inserted: - __context_names: - - dynamic_table_refresh_history - __example: "100" - __description: The number of rows inserted during the refresh. - displayName: Rows Inserted - unit: rows - snowflake.table.dynamic.lag.max: - __context_names: - - dynamic_tables - __example: "83" - __description: - The maximum lag time in seconds of refreshes for this dynamic - table. - displayName: Maximum Lag Time - unit: seconds - snowflake.table.dynamic.lag.mean: - __context_names: - - dynamic_tables - __example: "26" - __description: - The mean lag time (in seconds) of refreshes for this dynamic - table. - displayName: Mean Lag Time - unit: seconds - snowflake.table.dynamic.lag.target.time_above: - __context_names: - - dynamic_tables - __example: "151" - __description: - The time in seconds when the actual lag was more than the defined - target lag. - displayName: Time Above Target Lag - unit: seconds - snowflake.table.dynamic.lag.target.value: - __context_names: - - dynamic_table_refresh_history - - dynamic_table_graph_history - __example: "60" - __description: - The time in seconds in the retention period or since the last - configuration change, when the actual lag was more than the defined target - lag. - displayName: Target Lag Time - unit: seconds - snowflake.table.dynamic.lag.target.within_ratio: - __context_names: - - dynamic_tables - __example: "0.999" - __description: - The ratio of time in the retention period or since the last configuration - change, when actual lag is within the target lag. - displayName: Time Within Target Lag Ratio - unit: ratio + snowflake.partitions.added: + __context_names: + - dynamic_table_refresh_history + __example: "5" + __description: The number of partitions added during the refresh. + displayName: Partitions Added + unit: partitions + snowflake.partitions.removed: + __context_names: + - dynamic_table_refresh_history + __example: "3" + __description: The number of partitions removed during the refresh. + displayName: Partitions Removed + unit: partitions + snowflake.rows.copied: + __context_names: + - dynamic_table_refresh_history + __example: "75" + __description: The number of rows copied during the refresh. + displayName: Rows Copied + unit: rows + snowflake.rows.deleted: + __context_names: + - dynamic_table_refresh_history + __example: "50" + __description: The number of rows deleted during the refresh. + displayName: Rows Deleted + unit: rows + snowflake.rows.inserted: + __context_names: + - dynamic_table_refresh_history + __example: "100" + __description: The number of rows inserted during the refresh. + displayName: Rows Inserted + unit: rows + snowflake.table.dynamic.lag.max: + __context_names: + - dynamic_tables + __example: "83" + __description: The maximum lag time in seconds of refreshes for this dynamic table. + displayName: Maximum Lag Time + unit: seconds + snowflake.table.dynamic.lag.mean: + __context_names: + - dynamic_tables + __example: "26" + __description: The mean lag time (in seconds) of refreshes for this dynamic table. + displayName: Mean Lag Time + unit: seconds + snowflake.table.dynamic.lag.target.time_above: + __context_names: + - dynamic_tables + __example: "151" + __description: The time in seconds when the actual lag was more than the defined target lag. + displayName: Time Above Target Lag + unit: seconds + snowflake.table.dynamic.lag.target.value: + __context_names: + - dynamic_table_refresh_history + - dynamic_table_graph_history + __example: "60" + __description: + The time in seconds in the retention period or since the last configuration change, when the actual lag was more than the defined + target lag. + displayName: Target Lag Time + unit: seconds + snowflake.table.dynamic.lag.target.within_ratio: + __context_names: + - dynamic_tables + __example: "0.999" + __description: + The ratio of time in the retention period or since the last configuration change, when actual lag is within the target lag. + displayName: Time Within Target Lag Ratio + unit: ratio diff --git a/src/dtagent/plugins/dynamic_tables.py b/src/dtagent/plugins/dynamic_tables.py index e7513fbf..22a21350 100644 --- a/src/dtagent/plugins/dynamic_tables.py +++ b/src/dtagent/plugins/dynamic_tables.py @@ -27,9 +27,9 @@ # # -import uuid from typing import Tuple, Dict from dtagent.plugins import Plugin +from dtagent.context import RUN_PLUGIN_KEY, RUN_RESULTS_KEY, RUN_ID_KEY # COMPILE_REMOVE ##endregion COMPILE_REMOVE @@ -41,15 +41,20 @@ class DynamicTablesPlugin(Plugin): Dynamic tables plugin class. """ - def process(self, run_proc: bool = True) -> Dict[str, Dict[str, int]]: + def process(self, run_id: str, run_proc: bool = True) -> Dict[str, Dict[str, int]]: """ Processes the measures on dynamic tables + Args: + run_id (str): unique run identifier + run_proc (bool): indicator whether processing should be logged as completed + Returns: Dict[str,int]: A dictionary with counts of processed telemetry data. Example: { + "dsoa.run.results": { "dynamic_tables": { "entries": entries_cnt, "log_lines": logs_cnt, @@ -68,14 +73,14 @@ def process(self, run_proc: bool = True) -> Dict[str, Dict[str, int]]: "metrics": metrics_graph_cnt, "events": event_graph_cnt, }, + }, + "dsoa.run.id": "uuid_string" } """ t_dynamic_tables = "APP.V_DYNAMIC_TABLES_INSTRUMENTED" t_dynamic_table_refresh_history = "APP.V_DYNAMIC_TABLE_REFRESH_HISTORY_INSTRUMENTED" t_dynamic_table_graph_history = "APP.V_DYNAMIC_TABLE_GRAPH_HISTORY_INSTRUMENTED" - run_id = str(uuid.uuid4().hex) - (entries_cnt, logs_cnt, metrics_cnt, event_cnt) = self._log_entries( lambda: self._get_table_rows(t_dynamic_tables), "dynamic_tables", @@ -101,24 +106,28 @@ def process(self, run_proc: bool = True) -> Dict[str, Dict[str, int]]: ) return { - "dynamic_tables": { - "entries": entries_cnt, - "log_lines": logs_cnt, - "metrics": metrics_cnt, - "events": event_cnt, - }, - "dynamic_table_refresh_history": { - "entries": entries_refresh_cnt, - "log_lines": logs_refresh_cnt, - "metrics": metrics_refresh_cnt, - "events": event_refresh_cnt, - }, - "dynamic_table_graph_history": { - "entries": entries_graph_cnt, - "log_lines": logs_graph_cnt, - "metrics": metrics_graph_cnt, - "events": event_graph_cnt, + RUN_PLUGIN_KEY: "dynamic_tables", + RUN_RESULTS_KEY: { + "dynamic_tables": { + "entries": entries_cnt, + "log_lines": logs_cnt, + "metrics": metrics_cnt, + "events": event_cnt, + }, + "dynamic_table_refresh_history": { + "entries": entries_refresh_cnt, + "log_lines": logs_refresh_cnt, + "metrics": metrics_refresh_cnt, + "events": event_refresh_cnt, + }, + "dynamic_table_graph_history": { + "entries": entries_graph_cnt, + "log_lines": logs_graph_cnt, + "metrics": metrics_graph_cnt, + "events": event_graph_cnt, + }, }, + RUN_ID_KEY: run_id, } diff --git a/src/dtagent/plugins/dynamic_tables.sql/032_p_grant_monitor_dynamic_tables.sql b/src/dtagent/plugins/dynamic_tables.sql/032_p_grant_monitor_dynamic_tables.sql index 3d639d16..ec492796 100644 --- a/src/dtagent/plugins/dynamic_tables.sql/032_p_grant_monitor_dynamic_tables.sql +++ b/src/dtagent/plugins/dynamic_tables.sql/032_p_grant_monitor_dynamic_tables.sql @@ -35,8 +35,8 @@ execute as caller as $$ DECLARE - q_show_databases TEXT DEFAULT 'show databases'; - c_database_names CURSOR FOR with cte_includes as ( + c_database_names CURSOR FOR SHOW DATABASES ->> + with cte_includes as ( select distinct split_part(ci.VALUE, '.', 0) as db_pattern from CONFIG.CONFIGURATIONS c, table(flatten(c.VALUE)) ci where c.PATH = 'plugins.dynamic_tables.include' @@ -56,9 +56,6 @@ DECLARE q_grant_monitor_all TEXT DEFAULT ''; q_grant_monitor_future TEXT DEFAULT ''; BEGIN - -- list all warehouses - EXECUTE IMMEDIATE :q_show_databases; - -- iterate over warehouses FOR r_db IN c_database_names DO q_grant_monitor_all := 'grant monitor on all dynamic tables in database ' || r_db.name || ' to role DTAGENT_VIEWER;'; diff --git a/src/dtagent/plugins/event_log.config/bom.yml b/src/dtagent/plugins/event_log.config/bom.yml index d2f8d13b..86baa81a 100644 --- a/src/dtagent/plugins/event_log.config/bom.yml +++ b/src/dtagent/plugins/event_log.config/bom.yml @@ -3,7 +3,8 @@ delivers: type: table|view comment: | Dynatrace Snowflake Observability Agent can setup an event table if one does not exist. - It creates a view over an existing event log table if that table was not setup by the actual Dynatrace Snowflake Observability Agent instance. + It creates a view over an existing event log table if that table was not setup by the actual + Dynatrace Snowflake Observability Agent instance. - name: DTAGENT_DB.APP.SETUP_EVENT_TABLE() type: procedure - name: DTAGENT_DB.APP.P_CLEANUP_EVENT_LOG() @@ -36,4 +37,4 @@ references: - name: $event_table privileges: SELECT granted to: DTAGENT_VIEW - comment: This is in case an event log table was not setup by this Dynatrace Snowflake Observability Agent instance \ No newline at end of file + comment: This is in case an event log table was not setup by this Dynatrace Snowflake Observability Agent instance diff --git a/src/dtagent/plugins/event_log.config/instruments-def.yml b/src/dtagent/plugins/event_log.config/instruments-def.yml index f2976e58..fa8faf95 100644 --- a/src/dtagent/plugins/event_log.config/instruments-def.yml +++ b/src/dtagent/plugins/event_log.config/instruments-def.yml @@ -18,9 +18,7 @@ dimensions: db.namespace: __example: PROD_DB - __description: - The name of the database that was specified in the context of - the query at compilation. + __description: The name of the database that was specified in the context of the query at compilation. __context_names: - event_log_metrics - event_log_spans diff --git a/src/dtagent/plugins/event_log.py b/src/dtagent/plugins/event_log.py index 786b1b4f..0f99b850 100644 --- a/src/dtagent/plugins/event_log.py +++ b/src/dtagent/plugins/event_log.py @@ -28,10 +28,10 @@ # import logging from typing import Dict, Generator, Tuple -import uuid import pandas as pd from dtagent.util import _unpack_json_dict from dtagent.plugins import Plugin +from dtagent.context import RUN_PLUGIN_KEY, RUN_RESULTS_KEY, RUN_ID_KEY # COMPILE_REMOVE ##endregion COMPILE_REMOVE @@ -149,15 +149,20 @@ def _process_span_entries(self, run_id, run_proc: bool = True) -> Tuple[int, int metrics_sent, ) - def process(self, run_proc: bool = True) -> Dict[str, Dict[str, int]]: + def process(self, run_id: str, run_proc: bool = True) -> Dict[str, Dict[str, int]]: """ Analyzes changes in the event log + Args: + run_id (str): unique run identifier + run_proc (bool): indicator whether processing should be logged as completed + Returns: Dict[str, Dict[str, int]: A dictionary with counts of processed telemetry data. Example: { + "dsoa.run.results": { "event_log": { "entries": l_entries_cnt, "log_lines": l_logs_cnt, @@ -178,10 +183,10 @@ def process(self, run_proc: bool = True) -> Dict[str, Dict[str, int]]: "span_events": s_span_events_added, "errors": s_errors_count, }, + }, + "dsoa.run.id": "uuid_string" } """ - run_id = str(uuid.uuid4().hex) - ( s_entries_cnt, s_errors_count, @@ -194,26 +199,30 @@ def process(self, run_proc: bool = True) -> Dict[str, Dict[str, int]]: l_entries_cnt, l_logs_cnt, l_metrics_cnt, l_events_cnt = self._process_log_entries(run_id, run_proc) return { - "event_log": { - "entries": l_entries_cnt, - "log_lines": l_logs_cnt, - "metrics": l_metrics_cnt, - "events": l_events_cnt, - }, - "event_log_metrics": { - "entries": m_entries_cnt, - "log_lines": m_logs_cnt, - "metrics": m_metrics_cnt, - "events": m_event_cnt, - }, - "event_log_spans": { - "entries": s_entries_cnt, - "log_lines": s_logs_sent, - "metrics": s_metrics_sent, - "spans": s_spans_sent, - "span_events": s_span_events_added, - "errors": s_errors_count, + RUN_PLUGIN_KEY: "event_log", + RUN_RESULTS_KEY: { + "event_log": { + "entries": l_entries_cnt, + "log_lines": l_logs_cnt, + "metrics": l_metrics_cnt, + "events": l_events_cnt, + }, + "event_log_metrics": { + "entries": m_entries_cnt, + "log_lines": m_logs_cnt, + "metrics": m_metrics_cnt, + "events": m_event_cnt, + }, + "event_log_spans": { + "entries": s_entries_cnt, + "log_lines": s_logs_sent, + "metrics": s_metrics_sent, + "spans": s_spans_sent, + "span_events": s_span_events_added, + "errors": s_errors_count, + }, }, + RUN_ID_KEY: run_id, } diff --git a/src/dtagent/plugins/event_usage.config/bom.yml b/src/dtagent/plugins/event_usage.config/bom.yml index 0cf2b5ef..fd440e1b 100644 --- a/src/dtagent/plugins/event_usage.config/bom.yml +++ b/src/dtagent/plugins/event_usage.config/bom.yml @@ -9,4 +9,4 @@ delivers: references: - name: SNOWFLAKE.ACCOUNT_USAGE.EVENT_USAGE_HISTORY type: view - privileges: SELECT \ No newline at end of file + privileges: SELECT diff --git a/src/dtagent/plugins/event_usage.py b/src/dtagent/plugins/event_usage.py index 8e2bcfb3..34c187d4 100644 --- a/src/dtagent/plugins/event_usage.py +++ b/src/dtagent/plugins/event_usage.py @@ -26,10 +26,10 @@ # SOFTWARE. # # - from typing import Tuple, Dict from dtagent.util import _unpack_json_dict from dtagent.plugins import Plugin +from dtagent.context import RUN_PLUGIN_KEY, RUN_RESULTS_KEY, RUN_ID_KEY # COMPILE_REMOVE ##endregion COMPILE_REMOVE @@ -59,34 +59,48 @@ def _report_event_usage_log(self, row_dict: Dict, __context: Dict, log_level: in ) return True - def process(self, run_proc: bool = True) -> Dict[str, Dict[str, int]]: + def process(self, run_id: str, run_proc: bool = True) -> Dict[str, Dict[str, int]]: """ Processes data for event usage plugin. + + Args: + run_id (str): unique run identifier + run_proc (bool): indicator whether processing should be logged as completed + Returns: Dict[str,int]: A dictionary with counts of processed telemetry data. Example: { - "entries": entries_cnt, - "log_lines": logs_cnt, - "metrics": metrics_cnt, - "events": events_cnt + "dsoa.run.results": { + "event_usage": { + "entries": entries_cnt, + "log_lines": logs_cnt, + "metrics": metrics_cnt, + "events": events_cnt + }, + }, + "dsoa.run.id": "uuid_string" } """ - processed_entries_cnt, processed_logs_cnt, processed_event_metrics_cnt, processed_events_cnt = self._log_entries( f_entry_generator=lambda: self._get_table_rows("APP.V_EVENT_USAGE_HISTORY"), context_name="event_usage", + run_uuid=run_id, report_timestamp_events=False, log_completion=run_proc, f_report_log=self._report_event_usage_log, ) return { - "event_usage": { - "entries": processed_entries_cnt, - "log_lines": processed_logs_cnt, - "metrics": processed_event_metrics_cnt, - "events": processed_events_cnt, - } + RUN_PLUGIN_KEY: "event_usage", + RUN_RESULTS_KEY: { + "event_usage": { + "entries": processed_entries_cnt, + "log_lines": processed_logs_cnt, + "metrics": processed_event_metrics_cnt, + "events": processed_events_cnt, + }, + }, + RUN_ID_KEY: run_id, } diff --git a/src/dtagent/plugins/login_history.config/bom.yml b/src/dtagent/plugins/login_history.config/bom.yml index 74bd798e..92618e2a 100644 --- a/src/dtagent/plugins/login_history.config/bom.yml +++ b/src/dtagent/plugins/login_history.config/bom.yml @@ -14,4 +14,4 @@ references: privileges: SELECT - name: SNOWFLAKE.ACCOUNT_USAGE.SESSIONS type: view - privileges: SELECT \ No newline at end of file + privileges: SELECT diff --git a/src/dtagent/plugins/login_history.py b/src/dtagent/plugins/login_history.py index cf15af4f..84c22d52 100644 --- a/src/dtagent/plugins/login_history.py +++ b/src/dtagent/plugins/login_history.py @@ -27,11 +27,11 @@ # # -import uuid from typing import Tuple, Dict from dtagent.otel.events import EventType from dtagent.util import _unpack_payload from dtagent.plugins import Plugin +from dtagent.context import RUN_PLUGIN_KEY, RUN_RESULTS_KEY, RUN_ID_KEY # COMPILE_REMOVE ##endregion COMPILE_REMOVE @@ -59,15 +59,20 @@ def _prepare_event_payload_failed_login(self, row_dict: dict) -> Tuple[EventType } return EventType.CUSTOM_ALERT, "Failed login attempt", payload - def process(self, run_proc: bool = True) -> Dict[str, Dict[str, int]]: + def process(self, run_id: str, run_proc: bool = True) -> Dict[str, Dict[str, int]]: """ Processes the measures on login history. + Args: + run_id (str): unique run identifier + run_proc (bool): indicator whether processing should be logged as completed + Returns: Dict[str,int]: A dictionary with counts of processed telemetry data. Example: { + "dsoa.run.results": { "login_history": { "entries": entries_cnt, "log_lines": logs_cnt, @@ -80,13 +85,13 @@ def process(self, run_proc: bool = True) -> Dict[str, Dict[str, int]]: "metrics": metrics_cnt, "events": event_cnt, }, + }, + "dsoa.run.id": "uuid_string" } """ t_sessions = "APP.V_SESSIONS" t_login_history = "APP.V_LOGIN_HISTORY" - run_id = str(uuid.uuid4().hex) - login_history_entries_cnt, login_history_logs_cnt, login_history_metrics_cnt, login_history_events_cnt = self._log_entries( f_entry_generator=lambda: self._get_table_rows(t_login_history), context_name="login_history", @@ -105,18 +110,22 @@ def process(self, run_proc: bool = True) -> Dict[str, Dict[str, int]]: ) return { - "login_history": { - "entries": login_history_entries_cnt, - "log_lines": login_history_logs_cnt, - "metrics": login_history_metrics_cnt, - "events": login_history_events_cnt, - }, - "sessions": { - "entries": sessions_entries_cnt, - "log_lines": session_logs_cnt, - "metrics": session_metrics_cnt, - "events": session_events_cnt, + RUN_PLUGIN_KEY: "login_history", + RUN_RESULTS_KEY: { + "login_history": { + "entries": login_history_entries_cnt, + "log_lines": login_history_logs_cnt, + "metrics": login_history_metrics_cnt, + "events": login_history_events_cnt, + }, + "sessions": { + "entries": sessions_entries_cnt, + "log_lines": session_logs_cnt, + "metrics": session_metrics_cnt, + "events": session_events_cnt, + }, }, + RUN_ID_KEY: run_id, } diff --git a/src/dtagent/plugins/query_history.config/bom.yml b/src/dtagent/plugins/query_history.config/bom.yml index 9969ad6c..3337b23b 100644 --- a/src/dtagent/plugins/query_history.config/bom.yml +++ b/src/dtagent/plugins/query_history.config/bom.yml @@ -43,4 +43,4 @@ references: privileges: ALTER - name: SHOW WAREHOUSES type: command - privileges: USAGE \ No newline at end of file + privileges: USAGE diff --git a/src/dtagent/plugins/query_history.config/instruments-def.yml b/src/dtagent/plugins/query_history.config/instruments-def.yml index 9a99e3b3..7c4f7841 100644 --- a/src/dtagent/plugins/query_history.config/instruments-def.yml +++ b/src/dtagent/plugins/query_history.config/instruments-def.yml @@ -15,452 +15,402 @@ # * # * Catalog of instrumentation known to Dynatrace Snowflake Observability Agent - query history plugin attributes: - authentication.type: - __example: PASSWORD - __description: The authentication method used for the session. - client.application.id: - __example: app123 - __description: The ID of the client application used to execute the query. - client.application.version: - __example: 1.0.0 - __description: The version of the client application used to execute the query. - client.build_id: - __example: build123 - __description: The build ID of the client application. - client.environment: - __example: production - __description: The environment of the client application. - client.version: - __example: 1.0.0 - __description: The version of the client. - db.query.text: - __example: SELECT * FROM users; - __description: The text of the query. - db.snowflake.tables: - __example: users - __description: The tables involved in the query. - db.snowflake.views: - __example: user_view - __description: The views involved in the query. - event.id: - __example: login123 - __description: The login event ID associated with the query. - session.id: - __example: "1234567890" - __description: The session ID during which the query was executed. - dsoa.debug.span.events.added: - __example: 5 - __description: - Internal debug field indicating the number of span events successfully - added to the given span. - dsoa.debug.span.events.failed: - __example: 1 - __description: - Internal debug field indicating the number of span events that - failed to be added to the given span. - snowflake.cluster_number: - __example: cluster1 - __description: The cluster number associated with the query. - snowflake.database.id: - __example: db123 - __description: The unique identifier of the database involved in the query. - snowflake.error.code: - __example: ERR123 - __description: The error code returned by the query, if any. - snowflake.error.message: - __example: Syntax error - __description: The error message returned by the query, if any. - snowflake.query.with_operator_stats: - __example: true - __description: - Indicates if the query was executed with operator-level statistics - enabled. - snowflake.query.accel_est.estimated_query_times: - __example: '{ "scaleFactor1": 10, "scaleFactor2": 5 }' - __description: - Object that contains the estimated query execution time in seconds - for different query acceleration scale factors. If the status for the - query is not eligible for query acceleration, this object is empty. - snowflake.query.accel_est.status: - __example: eligible - __description: - "Indicates whether the query is eligible to benefit from - the query acceleration service. Possible values are: eligible, ineligible, - accelerated, invalid." - snowflake.query.accel_est.upper_limit_scale_factor: - __example: 2 - __description: - Number of the highest query acceleration scale factor in the - estimatedQueryTimes object. If the status for the query is not eligible - for query acceleration, this field is set to 0. - snowflake.query.data_transfer.inbound.cloud: - __example: AWS - __description: The cloud provider from which data was transferred inbound. - snowflake.query.data_transfer.inbound.region: - __example: us-west-2 - __description: The region from which data was transferred inbound. - snowflake.query.data_transfer.outbound.cloud: - __example: AWS - __description: The cloud provider to which data was transferred outbound. - snowflake.query.data_transfer.outbound.region: - __example: us-west-2 - __description: The region to which data was transferred outbound. - snowflake.query.hash: - __example: hash123 - __description: The hash of the query text. - snowflake.query.hash_version: - __example: v1 - __description: The version of the query hash. - snowflake.query.id: - __example: b1bbaa7f-8144-4e50-947a-b7e9bf7d62d5 - __description: The unique identifier for the query. - snowflake.query.is_client_generated: - __example: "true" - __description: Indicates if the statement was generated by the client. - snowflake.query.operator.attributes: - __example: - '{ "equality_join_condition": "(T4.C = T1.C)", "join_type": "INNER" - }' - __description: Information about the operator, depending on the operator type. - snowflake.query.operator.id: - __example: 0 - __description: - The operator’s identifier, unique within the query. Values start - at 0. - snowflake.query.operator.parent_ids: - __example: "[0]" - __description: - Identifiers of the parent operators for this operator, or NULL - if this is the final operator in the query plan. - snowflake.query.operator.stats: - __example: '{ "input_rows": 64, "output_rows": 64 }' - __description: - Statistics about the operator (e.g., the number of output rows - from the operator). - snowflake.query.operator.time: - __example: - '{ "overall_percentage": 50.0,"initialization": 0.5,"processing": - 4.0,"synchronization": 0.5,"local_disk_io": 0.2,"remote_disk_io": 0.1,"network_communication": - 0.2 }' - __description: | - The breakdown of the execution time of the operator: - - **overall_percentage**: The percentage of the total query time spent by this operator, - - **initialization**: Time spent setting up query processing, - - **processing**: Time spent processing the data by the CPU, - - **synchronization**: Time spent synchronizing activities between participating processes, - - **local_disk_io**: Time during which processing was blocked while waiting for local disk access, - - **remote_disk_io**: Time during which processing was blocked while waiting for remote disk access, - - **network_communication**: Time during which processing was waiting for network data transfer. - snowflake.query.operator.type: - __example: TableScan - __description: The type of query operator (e.g., TableScan or Filter). - snowflake.query.parametrized_hash: - __example: param_hash123 - __description: The hash of the parameterized query text. - snowflake.query.parametrized_hash_version: - __example: v1 - __description: The version of the parameterized query hash. - snowflake.query.parent_id: - __example: parent123 - __description: The unique identifier for the parent query, if applicable. - snowflake.query.retry_cause: - __example: Network issue - __description: The cause for retrying the query, if applicable. - snowflake.query.step.id: - __example: 1 - __description: Identifier of the step in the query plan. - snowflake.query.tag: - __example: tag1 - __description: The tag associated with the query. - snowflake.query.transaction_id: - __example: txn123 - __description: The transaction ID associated with the query. - snowflake.release_version: - __example: "5.0" - __description: The release version of Snowflake at the time of query execution. - snowflake.role.type: - __example: PRIMARY - __description: The type of role used to execute the query. - snowflake.schema.id: - __example: schema123 - __description: The unique identifier of the schema involved in the query. - snowflake.schema.name: - __example: public - __description: The name of the schema involved in the query. - snowflake.secondary_role_stats: - __example: role_stat1 - __description: Statistics related to secondary roles used during the query execution. - snowflake.session.closed_reason: - __example: User logout - __description: The reason the session was closed. - snowflake.session.start: - __example: "2024-11-05T21:11:07Z" - __description: The start time of the session. - snowflake.warehouse.cluster.number: - __example: cluster1 - __description: The cluster number of the warehouse used. - snowflake.warehouse.id: - __example: wh123 - __description: The unique identifier of the warehouse used. - snowflake.warehouse.size: - __example: X-SMALL - __description: The size of the warehouse used. - snowflake.warehouse.type: - __example: STANDARD - __description: The type of warehouse used. + authentication.type: + __example: PASSWORD + __description: The authentication method used for the session. + client.application.id: + __example: app123 + __description: The ID of the client application used to execute the query. + client.application.version: + __example: 1.0.0 + __description: The version of the client application used to execute the query. + client.build_id: + __example: build123 + __description: The build ID of the client application. + client.environment: + __example: production + __description: The environment of the client application. + client.version: + __example: 1.0.0 + __description: The version of the client. + db.query.text: + __example: SELECT * FROM users; + __description: The text of the query. + db.snowflake.tables: + __example: users + __description: The tables involved in the query. + db.snowflake.views: + __example: user_view + __description: The views involved in the query. + event.id: + __example: login123 + __description: The login event ID associated with the query. + session.id: + __example: "1234567890" + __description: The session ID during which the query was executed. + dsoa.debug.span.events.added: + __example: 5 + __description: Internal debug field indicating the number of span events successfully added to the given span. + dsoa.debug.span.events.failed: + __example: 1 + __description: Internal debug field indicating the number of span events that failed to be added to the given span. + snowflake.cluster_number: + __example: cluster1 + __description: The cluster number associated with the query. + snowflake.database.id: + __example: db123 + __description: The unique identifier of the database involved in the query. + snowflake.error.code: + __example: ERR123 + __description: The error code returned by the query, if any. + snowflake.error.message: + __example: Syntax error + __description: The error message returned by the query, if any. + snowflake.query.with_operator_stats: + __example: true + __description: Indicates if the query was executed with operator-level statistics enabled. + snowflake.query.accel_est.estimated_query_times: + __example: '{ "scaleFactor1": 10, "scaleFactor2": 5 }' + __description: + Object that contains the estimated query execution time in seconds for different query acceleration scale factors. If the status for + the query is not eligible for query acceleration, this object is empty. + snowflake.query.accel_est.status: + __example: eligible + __description: + "Indicates whether the query is eligible to benefit from the query acceleration service. Possible values are: eligible, ineligible, + accelerated, invalid." + snowflake.query.accel_est.upper_limit_scale_factor: + __example: 2 + __description: + Number of the highest query acceleration scale factor in the estimatedQueryTimes object. If the status for the query is not eligible + for query acceleration, this field is set to 0. + snowflake.query.data_transfer.inbound.cloud: + __example: AWS + __description: The cloud provider from which data was transferred inbound. + snowflake.query.data_transfer.inbound.region: + __example: us-west-2 + __description: The region from which data was transferred inbound. + snowflake.query.data_transfer.outbound.cloud: + __example: AWS + __description: The cloud provider to which data was transferred outbound. + snowflake.query.data_transfer.outbound.region: + __example: us-west-2 + __description: The region to which data was transferred outbound. + snowflake.query.hash: + __example: hash123 + __description: The hash of the query text. + snowflake.query.hash_version: + __example: v1 + __description: The version of the query hash. + snowflake.query.id: + __example: b1bbaa7f-8144-4e50-947a-b7e9bf7d62d5 + __description: The unique identifier for the query. + snowflake.query.is_client_generated: + __example: "true" + __description: Indicates if the statement was generated by the client. + snowflake.query.operator.attributes: + __example: '{ "equality_join_condition": "(T4.C = T1.C)", "join_type": "INNER" }' + __description: Information about the operator, depending on the operator type. + snowflake.query.operator.id: + __example: 0 + __description: The operator’s identifier, unique within the query. Values start at 0. + snowflake.query.operator.parent_ids: + __example: "[0]" + __description: Identifiers of the parent operators for this operator, or NULL if this is the final operator in the query plan. + snowflake.query.operator.stats: + __example: '{ "input_rows": 64, "output_rows": 64 }' + __description: Statistics about the operator (e.g., the number of output rows from the operator). + snowflake.query.operator.time: + __example: + '{ "overall_percentage": 50.0,"initialization": 0.5,"processing": 4.0,"synchronization": 0.5,"local_disk_io": 0.2,"remote_disk_io": + 0.1,"network_communication": 0.2 }' + __description: | + The breakdown of the execution time of the operator: + - **overall_percentage**: The percentage of the total query time spent by this operator, + - **initialization**: Time spent setting up query processing, + - **processing**: Time spent processing the data by the CPU, + - **synchronization**: Time spent synchronizing activities between participating processes, + - **local_disk_io**: Time during which processing was blocked while waiting for local disk access, + - **remote_disk_io**: Time during which processing was blocked while waiting for remote disk access, + - **network_communication**: Time during which processing was waiting for network data transfer. + snowflake.query.operator.type: + __example: TableScan + __description: The type of query operator (e.g., TableScan or Filter). + snowflake.query.parametrized_hash: + __example: param_hash123 + __description: The hash of the parameterized query text. + snowflake.query.parametrized_hash_version: + __example: v1 + __description: The version of the parameterized query hash. + snowflake.query.parent_id: + __example: parent123 + __description: The unique identifier for the parent query, if applicable. + snowflake.query.retry_cause: + __example: Network issue + __description: The cause for retrying the query, if applicable. + snowflake.query.step.id: + __example: 1 + __description: Identifier of the step in the query plan. + snowflake.query.tag: + __example: tag1 + __description: The tag associated with the query. + snowflake.query.transaction_id: + __example: txn123 + __description: The transaction ID associated with the query. + snowflake.release_version: + __example: "5.0" + __description: The release version of Snowflake at the time of query execution. + snowflake.role.type: + __example: PRIMARY + __description: The type of role used to execute the query. + snowflake.schema.id: + __example: schema123 + __description: The unique identifier of the schema involved in the query. + snowflake.schema.name: + __example: public + __description: The name of the schema involved in the query. + snowflake.secondary_role_stats: + __example: role_stat1 + __description: Statistics related to secondary roles used during the query execution. + snowflake.session.closed_reason: + __example: User logout + __description: The reason the session was closed. + snowflake.session.start: + __example: "2024-11-05T21:11:07Z" + __description: The start time of the session. + snowflake.warehouse.cluster.number: + __example: cluster1 + __description: The cluster number of the warehouse used. + snowflake.warehouse.id: + __example: wh123 + __description: The unique identifier of the warehouse used. + snowflake.warehouse.size: + __example: X-SMALL + __description: The size of the warehouse used. + snowflake.warehouse.type: + __example: STANDARD + __description: The type of warehouse used. dimensions: - db.collection.name: - __example: users - __description: The name of the table involved in the query. - db.namespace: - __example: PROD_DB - __description: - The name of the database that was specified in the context of - the query at compilation. - db.operation.name: - __example: SELECT - __description: The type of operation performed by the query. - db.snowflake.dbs: - __example: PROD_DB - __description: The databases involved in the query. - db.user: - __example: admin - __description: Snowflake user who issued the query. - snowflake.query.execution_status: - __example: SUCCESS - __description: The execution status of the query. - snowflake.role.name: - __example: SYSADMIN - __description: The role used to execute the query. - snowflake.warehouse.name: - __example: COMPUTE_WH - __description: The warehouse used to execute the query. + db.collection.name: + __example: users + __description: The name of the table involved in the query. + db.namespace: + __example: PROD_DB + __description: The name of the database that was specified in the context of the query at compilation. + db.operation.name: + __example: SELECT + __description: The type of operation performed by the query. + db.snowflake.dbs: + __example: PROD_DB + __description: The databases involved in the query. + db.user: + __example: admin + __description: Snowflake user who issued the query. + snowflake.query.execution_status: + __example: SUCCESS + __description: The execution status of the query. + snowflake.role.name: + __example: SYSADMIN + __description: The role used to execute the query. + snowflake.warehouse.name: + __example: COMPUTE_WH + __description: The warehouse used to execute the query. metrics: - snowflake.acceleration.data.scanned: - __example: "2097152" - __description: Number of bytes scanned by the query acceleration service. - displayName: Query Acceleration Bytes Scanned - unit: bytes - snowflake.acceleration.partitions.scanned: - __example: "50" - __description: Number of partitions scanned by the query acceleration service. - displayName: Query Acceleration Partitions Scanned - unit: partitions - snowflake.acceleration.scale_factor.max: - __example: "4" - __description: Upper limit scale factor that a query would have benefited from. - displayName: Query Acceleration Upper Limit Scale Factor - unit: factor - snowflake.credits.cloud_services: - __example: "10" - __description: Number of credits used for cloud services. - displayName: Cloud Services Credits Used - unit: credits - snowflake.data.deleted: - __example: "1048576" - __description: Number of bytes deleted by the query. - displayName: Bytes Deleted - unit: bytes - snowflake.data.read.from_result: - __example: "1048576" - __description: Number of bytes read from a result object. - displayName: Bytes Read from Result - unit: bytes - snowflake.data.scanned: - __example: "10485760" - __description: Number of bytes scanned by this statement. - displayName: Bytes Scanned - unit: bytes - snowflake.data.scanned_from_cache: - __example: "75" - __description: - The percentage of data scanned from the local disk cache. The - value ranges from 0.0 to 1.0. Multiply by 100 to get a true percentage. - displayName: Percentage Scanned from Cache - unit: percent - snowflake.data.sent_over_the_network: - __example: "524288" - __description: Volume of data sent over the network. - displayName: Bytes Sent Over the Network - unit: bytes - snowflake.data.spilled.local: - __example: "1048576" - __description: Volume of data spilled to local disk. - displayName: Bytes Spilled to Local Storage - unit: bytes - snowflake.data.spilled.remote: - __example: "2097152" - __description: Volume of data spilled to remote disk. - displayName: Bytes Spilled to Remote Storage - unit: bytes - snowflake.data.transferred.inbound: - __example: "10485760" - __description: - Number of bytes transferred in statements that load data from - another region and/or cloud. - displayName: Inbound Data Transfer Bytes - unit: bytes - snowflake.data.transferred.outbound: - __example: "5242880" - __description: - Number of bytes transferred in statements that unload data to - another region and/or cloud. - displayName: Outbound Data Transfer Bytes - unit: bytes - snowflake.data.written: - __example: "2097152" - __description: Number of bytes written (e.g. when loading into a table). - displayName: Bytes Written - unit: bytes - snowflake.data.written_to_result: - __example: "1048576" - __description: Number of bytes written to a result object. - displayName: Bytes Written to Result - unit: bytes - snowflake.external_functions.data.received: - __example: "1048576" - __description: - The total number of bytes that this query received from all calls - to all remote services. - displayName: External Function Total Received Bytes - unit: bytes - snowflake.external_functions.data.sent: - __example: "524288" - __description: - The total number of bytes that this query sent in all calls to - all remote services. - displayName: External Function Total Sent Bytes - unit: bytes - snowflake.external_functions.invocations: - __example: "5" - __description: - The aggregate number of times that this query called remote services. - For important details, see the Usage Notes. - displayName: External Function Total Invocations - unit: count - snowflake.external_functions.rows.received: - __example: "1000" - __description: - The total number of rows that this query received from all calls - to all remote services. - displayName: External Function Total Received Rows - unit: rows - snowflake.external_functions.rows.sent: - __example: "500" - __description: - The total number of rows that this query sent in all calls to - all remote services. - displayName: External Function Total Sent Rows - unit: rows - snowflake.load.used: - __example: "85" - __description: - The approximate percentage of active compute resources in the - warehouse for this query execution. - displayName: Query Load Percent - unit: percent - snowflake.partitions.scanned: - __example: "100" - __description: Number of micro-partitions scanned. - displayName: Partitions Scanned - unit: partitions - snowflake.partitions.total: - __example: "500" - __description: Total micro-partitions of all tables included in this query. - displayName: Partitions Total - unit: partitions - snowflake.rows.deleted: - __example: "500" - __description: Number of rows deleted by the query. - displayName: Rows Deleted - unit: rows - snowflake.rows.inserted: - __example: "1000" - __description: Number of rows inserted by the query. - displayName: Rows Inserted - unit: rows - snowflake.rows.unloaded: - __example: "1000" - __description: Number of rows unloaded during data export. - displayName: Rows Unloaded - unit: rows - snowflake.rows.updated: - __example: "300" - __description: Number of rows updated by the query. - displayName: Rows Updated - unit: rows - snowflake.rows.written_to_result: - __example: "1" - __description: - Number of rows written to a result object. For CREATE TABLE AS - SELECT (CTAS) and all DML operations, this result is 1;. - displayName: Rows Written to Result - unit: rows - snowflake.time.child_queries_wait: - __example: "200" - __description: - Time (in milliseconds) to complete the cached lookup when calling - a memoizable function. - displayName: Child Queries Wait Time - unit: ms - snowflake.time.compilation: - __example: "5000" - __description: Compilation time (in milliseconds) - displayName: Query Compilation Time - unit: ms - snowflake.time.execution: - __example: "100000" - __description: Execution time (in milliseconds) - displayName: Execution Time - unit: ms - snowflake.time.fault_handling: - __example: "1500" - __description: - Total execution time (in milliseconds) for query retries caused - by errors that are not actionable. - displayName: Fault Handling Time - unit: ms - snowflake.time.list_external_files: - __example: "300" - __description: Time (in milliseconds) spent listing external files. - displayName: List External Files Time - unit: ms - snowflake.time.queued.overload: - __example: "1500" - __description: - Time (in milliseconds) spent in the warehouse queue, due to the - warehouse being overloaded by the current query workload. - displayName: Queued Overload Time - unit: ms - snowflake.time.queued.provisioning: - __example: "3000" - __description: - Time (in milliseconds) spent in the warehouse queue, waiting - for the warehouse compute resources to provision, due to warehouse creation, - resume, or resize. - displayName: Queued Provisioning Time - unit: ms - snowflake.time.repair: - __example: "500" - __description: - Time (in milliseconds) spent in the warehouse queue, waiting - for compute resources in the warehouse to be repaired. - displayName: Queued Repair Time - unit: ms - snowflake.time.retry: - __example: "2000" - __description: - Total execution time (in milliseconds) for query retries caused - by actionable errors. - displayName: Query Retry Time - unit: ms - snowflake.time.total_elapsed: - __example: "120000" - __description: Elapsed time (in milliseconds). - displayName: Total Elapsed Time - unit: ms - snowflake.time.transaction_blocked: - __example: "1000" - __description: Time (in milliseconds) spent blocked by a concurrent DML. - displayName: Transaction Blocked Time - unit: ms + snowflake.acceleration.data.scanned: + __example: "2097152" + __description: Number of bytes scanned by the query acceleration service. + displayName: Query Acceleration Bytes Scanned + unit: bytes + snowflake.acceleration.partitions.scanned: + __example: "50" + __description: Number of partitions scanned by the query acceleration service. + displayName: Query Acceleration Partitions Scanned + unit: partitions + snowflake.acceleration.scale_factor.max: + __example: "4" + __description: Upper limit scale factor that a query would have benefited from. + displayName: Query Acceleration Upper Limit Scale Factor + unit: factor + snowflake.credits.cloud_services: + __example: "10" + __description: Number of credits used for cloud services. + displayName: Cloud Services Credits Used + unit: credits + snowflake.data.deleted: + __example: "1048576" + __description: Number of bytes deleted by the query. + displayName: Bytes Deleted + unit: bytes + snowflake.data.read.from_result: + __example: "1048576" + __description: Number of bytes read from a result object. + displayName: Bytes Read from Result + unit: bytes + snowflake.data.scanned: + __example: "10485760" + __description: Number of bytes scanned by this statement. + displayName: Bytes Scanned + unit: bytes + snowflake.data.scanned_from_cache: + __example: "75" + __description: + The percentage of data scanned from the local disk cache. The value ranges from 0.0 to 1.0. Multiply by 100 to get a true percentage. + displayName: Percentage Scanned from Cache + unit: percent + snowflake.data.sent_over_the_network: + __example: "524288" + __description: Volume of data sent over the network. + displayName: Bytes Sent Over the Network + unit: bytes + snowflake.data.spilled.local: + __example: "1048576" + __description: Volume of data spilled to local disk. + displayName: Bytes Spilled to Local Storage + unit: bytes + snowflake.data.spilled.remote: + __example: "2097152" + __description: Volume of data spilled to remote disk. + displayName: Bytes Spilled to Remote Storage + unit: bytes + snowflake.data.transferred.inbound: + __example: "10485760" + __description: Number of bytes transferred in statements that load data from another region and/or cloud. + displayName: Inbound Data Transfer Bytes + unit: bytes + snowflake.data.transferred.outbound: + __example: "5242880" + __description: Number of bytes transferred in statements that unload data to another region and/or cloud. + displayName: Outbound Data Transfer Bytes + unit: bytes + snowflake.data.written: + __example: "2097152" + __description: Number of bytes written (e.g. when loading into a table). + displayName: Bytes Written + unit: bytes + snowflake.data.written_to_result: + __example: "1048576" + __description: Number of bytes written to a result object. + displayName: Bytes Written to Result + unit: bytes + snowflake.external_functions.data.received: + __example: "1048576" + __description: The total number of bytes that this query received from all calls to all remote services. + displayName: External Function Total Received Bytes + unit: bytes + snowflake.external_functions.data.sent: + __example: "524288" + __description: The total number of bytes that this query sent in all calls to all remote services. + displayName: External Function Total Sent Bytes + unit: bytes + snowflake.external_functions.invocations: + __example: "5" + __description: The aggregate number of times that this query called remote services. For important details, see the Usage Notes. + displayName: External Function Total Invocations + unit: count + snowflake.external_functions.rows.received: + __example: "1000" + __description: The total number of rows that this query received from all calls to all remote services. + displayName: External Function Total Received Rows + unit: rows + snowflake.external_functions.rows.sent: + __example: "500" + __description: The total number of rows that this query sent in all calls to all remote services. + displayName: External Function Total Sent Rows + unit: rows + snowflake.load.used: + __example: "85" + __description: The approximate percentage of active compute resources in the warehouse for this query execution. + displayName: Query Load Percent + unit: percent + snowflake.partitions.scanned: + __example: "100" + __description: Number of micro-partitions scanned. + displayName: Partitions Scanned + unit: partitions + snowflake.partitions.total: + __example: "500" + __description: Total micro-partitions of all tables included in this query. + displayName: Partitions Total + unit: partitions + snowflake.rows.deleted: + __example: "500" + __description: Number of rows deleted by the query. + displayName: Rows Deleted + unit: rows + snowflake.rows.inserted: + __example: "1000" + __description: Number of rows inserted by the query. + displayName: Rows Inserted + unit: rows + snowflake.rows.unloaded: + __example: "1000" + __description: Number of rows unloaded during data export. + displayName: Rows Unloaded + unit: rows + snowflake.rows.updated: + __example: "300" + __description: Number of rows updated by the query. + displayName: Rows Updated + unit: rows + snowflake.rows.written_to_result: + __example: "1" + __description: Number of rows written to a result object. For CREATE TABLE AS SELECT (CTAS) and all DML operations, this result is 1;. + displayName: Rows Written to Result + unit: rows + snowflake.time.child_queries_wait: + __example: "200" + __description: Time (in milliseconds) to complete the cached lookup when calling a memoizable function. + displayName: Child Queries Wait Time + unit: ms + snowflake.time.compilation: + __example: "5000" + __description: Compilation time (in milliseconds) + displayName: Query Compilation Time + unit: ms + snowflake.time.execution: + __example: "100000" + __description: Execution time (in milliseconds) + displayName: Execution Time + unit: ms + snowflake.time.fault_handling: + __example: "1500" + __description: Total execution time (in milliseconds) for query retries caused by errors that are not actionable. + displayName: Fault Handling Time + unit: ms + snowflake.time.list_external_files: + __example: "300" + __description: Time (in milliseconds) spent listing external files. + displayName: List External Files Time + unit: ms + snowflake.time.queued.overload: + __example: "1500" + __description: Time (in milliseconds) spent in the warehouse queue, due to the warehouse being overloaded by the current query workload. + displayName: Queued Overload Time + unit: ms + snowflake.time.queued.provisioning: + __example: "3000" + __description: + Time (in milliseconds) spent in the warehouse queue, waiting for the warehouse compute resources to provision, due to warehouse + creation, resume, or resize. + displayName: Queued Provisioning Time + unit: ms + snowflake.time.repair: + __example: "500" + __description: Time (in milliseconds) spent in the warehouse queue, waiting for compute resources in the warehouse to be repaired. + displayName: Queued Repair Time + unit: ms + snowflake.time.retry: + __example: "2000" + __description: Total execution time (in milliseconds) for query retries caused by actionable errors. + displayName: Query Retry Time + unit: ms + snowflake.time.total_elapsed: + __example: "120000" + __description: Elapsed time (in milliseconds). + displayName: Total Elapsed Time + unit: ms + snowflake.time.transaction_blocked: + __example: "1000" + __description: Time (in milliseconds) spent blocked by a concurrent DML. + displayName: Transaction Blocked Time + unit: ms diff --git a/src/dtagent/plugins/query_history.py b/src/dtagent/plugins/query_history.py index b6dfaea2..9ce867d0 100644 --- a/src/dtagent/plugins/query_history.py +++ b/src/dtagent/plugins/query_history.py @@ -26,7 +26,6 @@ # SOFTWARE. # # - import logging from typing import Any, Tuple, Dict, List from dtagent import LOG, LL_TRACE @@ -38,7 +37,7 @@ _pack_values_to_json_strings, ) from dtagent.plugins import Plugin -from dtagent.context import get_context_name_and_run_id +from dtagent.context import get_context_name_and_run_id, RUN_PLUGIN_KEY, RUN_RESULTS_KEY, RUN_ID_KEY # COMPILE_REMOVE ##endregion COMPILE_REMOVE @@ -50,15 +49,20 @@ class QueryHistoryPlugin(Plugin): Query history plugin class. """ - def process(self, run_proc: bool = True) -> Dict[str, Dict[str, int]]: + def process(self, run_id: str, run_proc: bool = True) -> Dict[str, Dict[str, int]]: """ The actual function to process query history: + Args: + run_id (str): unique run identifier + run_proc (bool): indicator whether processing should be logged as completed + Returns: Dict[str,Dict[str,int]]: A dictionary with telemetry counts for query history. Example: { + "dsoa.run.results": { "query_history": { "entries": processed_query_count, "log_lines": logs_sent, @@ -66,10 +70,12 @@ def process(self, run_proc: bool = True) -> Dict[str, Dict[str, int]]: "spans": spans_sent, "span_events": span_events_added, "errors": processing_errors_count, - } + }, + }, + "dsoa.run.id": "uuid_string" } """ - __context = get_context_name_and_run_id("query_history") + __context = get_context_name_and_run_id(plugin_name=self._plugin_name, context_name="query_history", run_id=run_id) def __get_query_operator_event_name(operator: Dict) -> str: """Returns string with query operator event.""" @@ -144,11 +150,11 @@ def __f_log_events(query_dict: Dict[str, Any]) -> int: self._session.call("APP.P_GET_ACCELERATION_ESTIMATES", log_on_exception=True) t_recent_queries = "APP.V_RECENT_QUERIES" - processed_query_ids, processing_errors_count, span_events_added, spans_sent, logs_sent, metrics_sent = self._process_span_rows( f_entry_generator=lambda: self._get_table_rows(t_recent_queries), view_name=t_recent_queries, context_name="query_history", + run_uuid=run_id, log_completion=run_proc, report_status=run_proc, f_span_events=__f_span_events, @@ -157,14 +163,18 @@ def __f_log_events(query_dict: Dict[str, Any]) -> int: # return (len(processed_query_ids), processing_errors_count, span_events_added, metrics_sent) return { - "query_history": { - "entries": len(processed_query_ids), - "log_lines": logs_sent, - "metrics": metrics_sent, - "spans": spans_sent, - "span_events": span_events_added, - "errors": processing_errors_count, - } + RUN_PLUGIN_KEY: "query_history", + RUN_RESULTS_KEY: { + "query_history": { + "entries": len(processed_query_ids), + "log_lines": logs_sent, + "metrics": metrics_sent, + "spans": spans_sent, + "span_events": span_events_added, + "errors": processing_errors_count, + }, + }, + RUN_ID_KEY: run_id, } diff --git a/src/dtagent/plugins/query_history.sql/060_p_monitor_warehouses.sql b/src/dtagent/plugins/query_history.sql/060_p_monitor_warehouses.sql index 4491adae..4a9da2de 100644 --- a/src/dtagent/plugins/query_history.sql/060_p_monitor_warehouses.sql +++ b/src/dtagent/plugins/query_history.sql/060_p_monitor_warehouses.sql @@ -33,8 +33,8 @@ execute as caller as $$ DECLARE - q_show_warehouses TEXT DEFAULT 'show warehouses'; - c_warehouse_names CURSOR FOR select "name" as name from TABLE(result_scan(last_query_id())) + c_warehouse_names CURSOR FOR SHOW WAREHOUSES ->> + select "name" as name from $1 where name not in ( select NAME from snowflake.account_usage.grants_to_roles @@ -47,10 +47,7 @@ DECLARE q_grant_monitor TEXT DEFAULT ''; BEGIN - -- list all warehouses - EXECUTE IMMEDIATE :q_show_warehouses; - - -- iterate over warehouses + -- iterate over unmonitored warehouses FOR r_wh IN c_warehouse_names DO q_grant_monitor := 'grant monitor on warehouse ' || r_wh.name || ' to role DTAGENT_VIEWER;'; diff --git a/src/dtagent/plugins/resource_monitors.config/instruments-def.yml b/src/dtagent/plugins/resource_monitors.config/instruments-def.yml index 6193a709..fa5080a7 100644 --- a/src/dtagent/plugins/resource_monitors.config/instruments-def.yml +++ b/src/dtagent/plugins/resource_monitors.config/instruments-def.yml @@ -16,169 +16,171 @@ # * Catalog of instrumentation known to Dynatrace Snowflake Observability Agent - resource monitors plugin attributes: - snowflake.budget.name: - __example: BUDGET_2024 - __description: The name of the budget associated with the warehouse. - snowflake.credits.quota: - __example: "1000" - __description: The credit quota of the resource monitor. - snowflake.credits.quota.remaining: - __example: "500" - __description: The remaining credits of the resource monitor. - snowflake.credits.quota.used: - __example: "500" - __description: The credits used by the resource monitor. - snowflake.resource_monitor.frequency: - __example: DAILY - __description: The frequency of the resource monitor. - snowflake.resource_monitor.is_active: - __example: "true" - __description: Indicates if the resource monitor is active. - snowflake.resource_monitor.level: - __example: ACCOUNT - __description: The level of the resource monitor. - snowflake.warehouse.execution_state: - __example: RUNNING - __description: The execution state of the warehouse. - snowflake.warehouse.has_query_acceleration_enabled: - __example: "true" - __description: Indicates if query acceleration is enabled for the warehouse. - snowflake.warehouse.is_auto_resume: - __example: "true" - __description: Indicates if the warehouse is set to auto-resume. - snowflake.warehouse.is_auto_suspend: - __example: "true" - __description: Indicates if the warehouse is set to auto-suspend. - snowflake.warehouse.is_current: - __example: "true" - __description: Indicates if the warehouse is the current warehouse. - snowflake.warehouse.is_default: - __example: "true" - __description: Indicates if the warehouse is the default warehouse. - snowflake.warehouse.is_unmonitored: - __example: "true" - __description: Indicates if the warehouse is NOT monitored by a resource monitor. - snowflake.warehouse.owner: - __example: admin - __description: The owner of the warehouse. - snowflake.warehouse.owner.role_type: - __example: SYSADMIN - __description: The role type of the warehouse owner. - snowflake.warehouse.scaling_policy: - __example: STANDARD - __description: The scaling policy of the warehouse. - snowflake.warehouse.size: - __example: X-SMALL - __description: The size of the warehouse. - snowflake.warehouse.type: - __example: STANDARD - __description: The type of the warehouse. - snowflake.warehouses.names: - __example: COMPUTE_WH - __description: The names of the warehouses monitored. + snowflake.budget.name: + __example: BUDGET_2024 + __description: The name of the budget associated with the warehouse. + snowflake.credits.quota: + __example: "1000" + __description: The credit quota of the resource monitor. + snowflake.credits.quota.remaining: + __example: "500" + __description: The remaining credits of the resource monitor. + snowflake.credits.quota.used: + __example: "500" + __description: The credits used by the resource monitor. + snowflake.resource_monitor.frequency: + __example: DAILY + __description: The frequency of the resource monitor. + snowflake.resource_monitor.is_active: + __example: "true" + __description: Indicates if the resource monitor is active. + snowflake.resource_monitor.level: + __example: ACCOUNT + __description: The level of the resource monitor. + snowflake.warehouse.execution_state: + __example: RUNNING + __description: The execution state of the warehouse. + snowflake.warehouse.has_query_acceleration_enabled: + __example: "true" + __description: Indicates if query acceleration is enabled for the warehouse. + snowflake.warehouse.is_auto_resume: + __example: "true" + __description: Indicates if the warehouse is set to auto-resume. + snowflake.warehouse.is_auto_suspend: + __example: "true" + __description: Indicates if the warehouse is set to auto-suspend. + snowflake.warehouse.is_current: + __example: "true" + __description: Indicates if the warehouse is the current warehouse. + snowflake.warehouse.is_default: + __example: "true" + __description: Indicates if the warehouse is the default warehouse. + snowflake.warehouse.is_unmonitored: + __example: "true" + __description: Indicates if the warehouse is NOT monitored by a resource monitor. + snowflake.warehouse.owner: + __example: admin + __description: The owner of the warehouse. + snowflake.warehouse.owner.role_type: + __example: SYSADMIN + __description: The role type of the warehouse owner. + snowflake.warehouse.scaling_policy: + __example: STANDARD + __description: The scaling policy of the warehouse. + snowflake.warehouse.size: + __example: X-SMALL + __description: The size of the warehouse. + snowflake.warehouse.type: + __example: STANDARD + __description: The type of the warehouse. + snowflake.warehouses.names: + __example: COMPUTE_WH + __description: The names of the warehouses monitored. dimensions: - snowflake.resource_monitor.name: - __example: RM_MONITOR - __description: The name of the resource monitor. - snowflake.warehouse.name: - __example: COMPUTE_WH - __description: The name of the warehouse. + snowflake.resource_monitor.name: + __example: RM_MONITOR + __description: The name of the resource monitor. + snowflake.warehouse.name: + __example: COMPUTE_WH + __description: The name of the warehouse. event_timestamps: - snowflake.resource_monitor.created_on: - __example: "2024-10-15 12:34:56.789" - __description: The timestamp when the resource monitor was created. - snowflake.resource_monitor.end_time: - __example: "2024-11-30 23:59:59.999" - __description: The timestamp when the resource monitor ended. - snowflake.resource_monitor.start_time: - __example: "2024-11-01 00:00:00.000" - __description: The timestamp when the resource monitor started. - snowflake.warehouse.created_on: - __example: "2024-09-01 08:00:00.000" - __description: The timestamp when the warehouse was created. - snowflake.warehouse.resumed_on: - __example: "2024-11-15 09:00:00.000" - __description: The timestamp when the warehouse was last resumed. - snowflake.warehouse.updated_on: - __example: "2024-11-10 14:30:00.000" - __description: The timestamp when the warehouse was last updated. - snowflake.event.trigger: - __example: "snowflake.warehouse.resumed_on" - __description: Additionally to sending logs, each entry in `EVENT_TIMESTAMPS` is sent as event with key set to `snowflake.event.trigger`, value to key from `EVENT_TIMESTAMPS` and `timestamp` set to the key value. + snowflake.resource_monitor.created_on: + __example: "2024-10-15 12:34:56.789" + __description: The timestamp when the resource monitor was created. + snowflake.resource_monitor.end_time: + __example: "2024-11-30 23:59:59.999" + __description: The timestamp when the resource monitor ended. + snowflake.resource_monitor.start_time: + __example: "2024-11-01 00:00:00.000" + __description: The timestamp when the resource monitor started. + snowflake.warehouse.created_on: + __example: "2024-09-01 08:00:00.000" + __description: The timestamp when the warehouse was created. + snowflake.warehouse.resumed_on: + __example: "2024-11-15 09:00:00.000" + __description: The timestamp when the warehouse was last resumed. + snowflake.warehouse.updated_on: + __example: "2024-11-10 14:30:00.000" + __description: The timestamp when the warehouse was last updated. + snowflake.event.trigger: + __example: "snowflake.warehouse.resumed_on" + __description: + Additionally to sending logs, each entry in `EVENT_TIMESTAMPS` is sent as event with key set to `snowflake.event.trigger`, value to + key from `EVENT_TIMESTAMPS` and `timestamp` set to the key value. metrics: - snowflake.acceleration.scale_factor.max: - __example: "2" - __description: Maximal scale factor for query acceleration in the given warehouse - displayName: Query Acceleration Upper Limit Scale Factor - unit: factor - snowflake.compute.available: - __example: "60" - __description: Percentage of available resources in given warehouse. - displayName: Percentage Available - unit: percent - snowflake.compute.other: - __example: "10" - __description: Percentage of other resources in given warehouse - displayName: Percentage Other - unit: percent - snowflake.compute.provisioning: - __example: "20" - __description: Percentage of provisioning resources in given warehouse. - displayName: Percentage Provisioning - unit: percent - snowflake.compute.quiescing: - __example: "10" - __description: Percentage of quiescing resources in given warehouse. - displayName: Percentage Quiescing - unit: percent - snowflake.credits.quota: - __example: "1000" - __description: Total number of credits allowed for the given resource monitor - displayName: Credits Quota - unit: credits - snowflake.credits.quota.remaining: - __example: "250" - __description: Number of credits remaining for the given resource monitor - displayName: Credits Remaining - unit: credits - snowflake.credits.quota.used: - __example: "750" - __description: Number of credits used by the given resource monitor - displayName: Credits Used - unit: credits - snowflake.credits.quota.used_pct: - __example: "75" - __description: Percentage of quota used by given resource monitor - displayName: Percentage Quota Used - unit: percent - snowflake.queries.queued: - __example: "5" - __description: Current number of queued queries in the given warehouse - displayName: Queued Queries - unit: queries - snowflake.queries.running: - __example: "15" - __description: Current number of running queries in the given warehouse - displayName: Running Queries - unit: queries - snowflake.resource_monitor.warehouses: - __example: "5" - __description: Number of warehouses monitored by the given resource monitor - displayName: Warehouses Count - unit: warehouses - snowflake.warehouse.clusters.max: - __example: "10" - __description: Maximal number of clusters in the given warehouse - displayName: Maximum Cluster Count - unit: clusters - snowflake.warehouse.clusters.min: - __example: "1" - __description: Minimal number of clusters in the given warehouse - displayName: Minimum Cluster Count - unit: clusters - snowflake.warehouse.clusters.started: - __example: "3" - __description: Current number of started clusters in the given warehouse - displayName: Started Clusters - unit: clusters + snowflake.acceleration.scale_factor.max: + __example: "2" + __description: Maximal scale factor for query acceleration in the given warehouse + displayName: Query Acceleration Upper Limit Scale Factor + unit: factor + snowflake.compute.available: + __example: "60" + __description: Percentage of available resources in given warehouse. + displayName: Percentage Available + unit: percent + snowflake.compute.other: + __example: "10" + __description: Percentage of other resources in given warehouse + displayName: Percentage Other + unit: percent + snowflake.compute.provisioning: + __example: "20" + __description: Percentage of provisioning resources in given warehouse. + displayName: Percentage Provisioning + unit: percent + snowflake.compute.quiescing: + __example: "10" + __description: Percentage of quiescing resources in given warehouse. + displayName: Percentage Quiescing + unit: percent + snowflake.credits.quota: + __example: "1000" + __description: Total number of credits allowed for the given resource monitor + displayName: Credits Quota + unit: credits + snowflake.credits.quota.remaining: + __example: "250" + __description: Number of credits remaining for the given resource monitor + displayName: Credits Remaining + unit: credits + snowflake.credits.quota.used: + __example: "750" + __description: Number of credits used by the given resource monitor + displayName: Credits Used + unit: credits + snowflake.credits.quota.used_pct: + __example: "75" + __description: Percentage of quota used by given resource monitor + displayName: Percentage Quota Used + unit: percent + snowflake.queries.queued: + __example: "5" + __description: Current number of queued queries in the given warehouse + displayName: Queued Queries + unit: queries + snowflake.queries.running: + __example: "15" + __description: Current number of running queries in the given warehouse + displayName: Running Queries + unit: queries + snowflake.resource_monitor.warehouses: + __example: "5" + __description: Number of warehouses monitored by the given resource monitor + displayName: Warehouses Count + unit: warehouses + snowflake.warehouse.clusters.max: + __example: "10" + __description: Maximal number of clusters in the given warehouse + displayName: Maximum Cluster Count + unit: clusters + snowflake.warehouse.clusters.min: + __example: "1" + __description: Minimal number of clusters in the given warehouse + displayName: Minimum Cluster Count + unit: clusters + snowflake.warehouse.clusters.started: + __example: "3" + __description: Current number of started clusters in the given warehouse + displayName: Started Clusters + unit: clusters diff --git a/src/dtagent/plugins/resource_monitors.py b/src/dtagent/plugins/resource_monitors.py index c514c18f..69094d59 100644 --- a/src/dtagent/plugins/resource_monitors.py +++ b/src/dtagent/plugins/resource_monitors.py @@ -26,13 +26,13 @@ # SOFTWARE. # # -import uuid import logging from typing import Tuple, Dict +from regex import R from snowflake.snowpark.functions import current_timestamp from dtagent.util import _unpack_json_dict from dtagent.plugins import Plugin -from dtagent.context import get_context_name_and_run_id +from dtagent.context import get_context_name_and_run_id, RUN_PLUGIN_KEY, RUN_RESULTS_KEY, RUN_ID_KEY # COMPILE_REMOVE from dtagent.otel.events import EventType ##endregion COMPILE_REMOVE @@ -100,14 +100,20 @@ def _process_log_wh(self, row_dict: Dict, __context: Dict, log_level: int) -> bo return False - def process(self, run_proc: bool = True) -> Dict[str, Dict[str, int]]: + def process(self, run_id: str, run_proc: bool = True) -> Dict[str, Dict[str, int]]: """ Processes the measures on resource monitors. + + Args: + run_id (str): unique run identifier + run_proc (bool): indicator whether processing should be logged as completed + Returns: Dict[str,int]: A dictionary with counts of processed telemetry data. Example: { + "dsoa.run.results": { "resource_monitors": { "entries": entries_cnt, "log_lines": logs_cnt, @@ -120,9 +126,10 @@ def process(self, run_proc: bool = True) -> Dict[str, Dict[str, int]]: "metrics": metrics_cnt, "events": events_cnt, }, + }, + "dsoa.run.id": "uuid_string" } """ - run_id = str(uuid.uuid4().hex) context_name = "resource_monitors" if run_proc: @@ -148,7 +155,7 @@ def process(self, run_proc: bool = True) -> Dict[str, Dict[str, int]]: self._logs.send_log( "There is no ACCOUNT level resource monitor setup", log_level=logging.ERROR, - context=get_context_name_and_run_id(context_name, run_id), + context=get_context_name_and_run_id(plugin_name=self._plugin_name, context_name=context_name, run_id=run_id), ) ( @@ -181,14 +188,9 @@ def process(self, run_proc: bool = True) -> Dict[str, Dict[str, int]]: } if run_proc: - self._report_execution( - "resource_monitors", - current_timestamp(), - None, - results_dict, - ) + self._report_execution("resource_monitors", current_timestamp(), None, results_dict, run_id=run_id) - return results_dict + return {RUN_PLUGIN_KEY: "resource_monitors", RUN_RESULTS_KEY: results_dict, RUN_ID_KEY: run_id} ##endregion diff --git a/src/dtagent/plugins/resource_monitors.sql/060_p_refresh_resource_monitors.sql b/src/dtagent/plugins/resource_monitors.sql/060_p_refresh_resource_monitors.sql index 4ddb5a16..d8a5e3d0 100644 --- a/src/dtagent/plugins/resource_monitors.sql/060_p_refresh_resource_monitors.sql +++ b/src/dtagent/plugins/resource_monitors.sql/060_p_refresh_resource_monitors.sql @@ -59,8 +59,8 @@ as $$ DECLARE tr_tmp_resource_monitors TEXT DEFAULT 'truncate table APP.TMP_RESOURCE_MONITORS;'; - q_show_resource_monitors TEXT DEFAULT 'show resource monitors;'; - q_pop_tmp_res_mon TEXT DEFAULT 'insert into APP.TMP_RESOURCE_MONITORS select + q_show_resource_monitors TEXT DEFAULT 'SHOW RESOURCE MONITORS ->> + insert into APP.TMP_RESOURCE_MONITORS select "name", "credit_quota", "used_credits", "remaining_credits", "level", "frequency", "start_time", "end_time", @@ -70,8 +70,8 @@ DECLARE from table(result_scan(last_query_id()));'; tr_tmp_warehouses TEXT DEFAULT 'truncate table APP.TMP_WAREHOUSES;'; - q_show_warehouses TEXT DEFAULT 'show warehouses;'; - q_pop_tmp_wh TEXT DEFAULT 'insert into APP.TMP_WAREHOUSES select + q_show_warehouses TEXT DEFAULT 'SHOW WAREHOUSES ->> + insert into APP.TMP_WAREHOUSES select "name", "state", "type", "size", "min_cluster_count", "max_cluster_count", "started_clusters", "running", "queued", @@ -90,11 +90,9 @@ DECLARE BEGIN EXECUTE IMMEDIATE :tr_tmp_resource_monitors; EXECUTE IMMEDIATE :q_show_resource_monitors; - EXECUTE IMMEDIATE :q_pop_tmp_res_mon; EXECUTE IMMEDIATE :tr_tmp_warehouses; EXECUTE IMMEDIATE :q_show_warehouses; - EXECUTE IMMEDIATE :q_pop_tmp_wh; RETURN 'tables APP.TMP_RESOURCE_MONITORS, APP.TMP_WAREHOUSES updated'; EXCEPTION diff --git a/src/dtagent/plugins/shares.config/instruments-def.yml b/src/dtagent/plugins/shares.config/instruments-def.yml index bb6602cd..293ca50c 100644 --- a/src/dtagent/plugins/shares.config/instruments-def.yml +++ b/src/dtagent/plugins/shares.config/instruments-def.yml @@ -14,216 +14,212 @@ # * Copyright (c) 2024 Dynatrace LLC. All rights reserved. # * attributes: - snowflake.data.rows: - __context_names: - - inbound_shares - __example: 20000 - __description: Number of rows in the table. - snowflake.data.size: - __context_names: - - inbound_shares - __example: 800000 - __description: Number of bytes accessed by a scan of the table. - snowflake.grant.by: - __context_names: - - outbound_shares - __example: ACCOUNTADMIN - __description: Shows the name of the account which made the grant. - snowflake.grant.grantee: - __context_names: - - outbound_shares - __example: PARTNER_ACCOUNT - __description: Shows the grantee account name. - snowflake.grant.on: - __context_names: - - outbound_shares - __example: DATABASE - __description: Shows on what type of object the grant was made. - snowflake.grant.option: - __context_names: - - outbound_shares - __example: false - __description: Indicates if grant option is available. - snowflake.grant.privilege: - __context_names: - - outbound_shares - __example: USAGE - __description: Shows the type of privilege granted. - snowflake.grant.to: - __context_names: - - outbound_shares - __example: SHARE - __description: Shows to what the grant was made. - snowflake.share.is_secure_objects_only: - __context_names: - - outbound_shares - - inbound_shares - __example: true - __description: Indicates if the share is only for secure objects. - snowflake.share.kind: - __context_names: - - outbound_shares - - inbound_shares - __example: OUTBOUND - __description: Indicates the type of share. - snowflake.share.listing_global_name: - __context_names: - - outbound_shares - - inbound_shares - __example: GLOBAL_SHARE_NAME - __description: Global name of the share listing. - snowflake.share.owner: - __context_names: - - outbound_shares - - inbound_shares - __example: ACCOUNTADMIN - __description: Shows the account owning the share. - snowflake.share.shared_from: - __context_names: - - outbound_shares - - inbound_shares - __example: SNOWFLAKE - __description: Shows the owner account of the share. - snowflake.share.shared_to: - __context_names: - - outbound_shares - - inbound_shares - __example: PARTNER_ACCOUNT - __description: Shows the account the share was made to. - snowflake.table.clustering_key: - __context_names: - - inbound_shares - __example: DATE - __description: Clustering key for the table. - snowflake.table.comment: - __context_names: - - inbound_shares - __example: - The tables defined in this database that are accessible to the - current user's role. - __description: Comment for this table. - snowflake.table.is_auto_clustering_on: - __context_names: - - inbound_shares - __example: "YES" - __description: Indicates whether automatic clustering is enabled for the table. - snowflake.table.is_dynamic: - __context_names: - - inbound_shares - __example: "NO" - __description: Indicates whether the table is a dynamic table. - snowflake.table.is_iceberg: - __context_names: - - inbound_shares - __example: "NO" - __description: Indicates whether the table is an Iceberg table. - snowflake.table.is_temporary: - __context_names: - - inbound_shares - __example: "NO" - __description: Indicates whether this is a temporary table. - snowflake.table.is_transient: - __context_names: - - inbound_shares - __example: "NO" - __description: Indicates whether this is a transient table. - snowflake.table.is_hybrid: - __context_names: - - inbound_shares - __example: FALSE - __description: Indicates whether this is a hybrid table. - snowflake.share.has_db_deleted: - __context_names: - - inbound_shares - __example: FALSE - __description: Indicates whether DB related to that INBOUND share has been deleted. - snowflake.share.has_details_reported: - __context_names: - - inbound_shares - __example: FALSE - __description: Indicates whether or not details on this share should be reported. - snowflake.table.last_ddl_by: - __context_names: - - inbound_shares - __example: DBA_USER - __description: The current username for the user who executed the last DDL operation. - snowflake.table.owner: - __context_names: - - inbound_shares - __example: ACCOUNTADMIN - __description: Name of the role that owns the table. - snowflake.table.retention_time: - __context_names: - - inbound_shares - __example: 5 - __description: Number of days that historical data is retained for Time Travel. - snowflake.table.type: - __context_names: - - inbound_shares - __example: BASE TABLE - __description: Indicates the table type. + snowflake.data.rows: + __context_names: + - inbound_shares + __example: 20000 + __description: Number of rows in the table. + snowflake.data.size: + __context_names: + - inbound_shares + __example: 800000 + __description: Number of bytes accessed by a scan of the table. + snowflake.grant.by: + __context_names: + - outbound_shares + __example: ACCOUNTADMIN + __description: Shows the name of the account which made the grant. + snowflake.grant.grantee: + __context_names: + - outbound_shares + __example: PARTNER_ACCOUNT + __description: Shows the grantee account name. + snowflake.grant.on: + __context_names: + - outbound_shares + __example: DATABASE + __description: Shows on what type of object the grant was made. + snowflake.grant.option: + __context_names: + - outbound_shares + __example: false + __description: Indicates if grant option is available. + snowflake.grant.privilege: + __context_names: + - outbound_shares + __example: USAGE + __description: Shows the type of privilege granted. + snowflake.grant.to: + __context_names: + - outbound_shares + __example: SHARE + __description: Shows to what the grant was made. + snowflake.share.is_secure_objects_only: + __context_names: + - outbound_shares + - inbound_shares + __example: true + __description: Indicates if the share is only for secure objects. + snowflake.share.kind: + __context_names: + - outbound_shares + - inbound_shares + __example: OUTBOUND + __description: Indicates the type of share. + snowflake.share.listing_global_name: + __context_names: + - outbound_shares + - inbound_shares + __example: GLOBAL_SHARE_NAME + __description: Global name of the share listing. + snowflake.share.owner: + __context_names: + - outbound_shares + - inbound_shares + __example: ACCOUNTADMIN + __description: Shows the account owning the share. + snowflake.share.shared_from: + __context_names: + - outbound_shares + - inbound_shares + __example: SNOWFLAKE + __description: Shows the owner account of the share. + snowflake.share.shared_to: + __context_names: + - outbound_shares + - inbound_shares + __example: PARTNER_ACCOUNT + __description: Shows the account the share was made to. + snowflake.table.clustering_key: + __context_names: + - inbound_shares + __example: DATE + __description: Clustering key for the table. + snowflake.table.comment: + __context_names: + - inbound_shares + __example: The tables defined in this database that are accessible to the current user's role. + __description: Comment for this table. + snowflake.table.is_auto_clustering_on: + __context_names: + - inbound_shares + __example: "YES" + __description: Indicates whether automatic clustering is enabled for the table. + snowflake.table.is_dynamic: + __context_names: + - inbound_shares + __example: "NO" + __description: Indicates whether the table is a dynamic table. + snowflake.table.is_iceberg: + __context_names: + - inbound_shares + __example: "NO" + __description: Indicates whether the table is an Iceberg table. + snowflake.table.is_temporary: + __context_names: + - inbound_shares + __example: "NO" + __description: Indicates whether this is a temporary table. + snowflake.table.is_transient: + __context_names: + - inbound_shares + __example: "NO" + __description: Indicates whether this is a transient table. + snowflake.table.is_hybrid: + __context_names: + - inbound_shares + __example: false + __description: Indicates whether this is a hybrid table. + snowflake.share.has_db_deleted: + __context_names: + - inbound_shares + __example: false + __description: Indicates whether DB related to that INBOUND share has been deleted. + snowflake.share.has_details_reported: + __context_names: + - inbound_shares + __example: false + __description: Indicates whether or not details on this share should be reported. + snowflake.table.last_ddl_by: + __context_names: + - inbound_shares + __example: DBA_USER + __description: The current username for the user who executed the last DDL operation. + snowflake.table.owner: + __context_names: + - inbound_shares + __example: ACCOUNTADMIN + __description: Name of the role that owns the table. + snowflake.table.retention_time: + __context_names: + - inbound_shares + __example: 5 + __description: Number of days that historical data is retained for Time Travel. + snowflake.table.type: + __context_names: + - inbound_shares + __example: BASE TABLE + __description: Indicates the table type. dimensions: - db.collection.name: - __context_names: - - inbound_shares - __example: SALES_DATA - __description: Name of the shared Snowflake table. - db.namespace: - __context_names: - - outbound_shares - - inbound_shares - __example: DEV_DB - __description: Name of the database used to store shared data. - snowflake.grant.name: - __context_names: - - outbound_shares - __example: READ_ACCESS - __description: Name of the grant to a share. - snowflake.schema.name: - __context_names: - - inbound_shares - __example: PUBLIC - __description: Name of the schema where the table is located. - snowflake.share.name: - __context_names: - - outbound_shares - - inbound_shares - __example: SAMPLE_DATA - __description: Name of the share. + db.collection.name: + __context_names: + - inbound_shares + __example: SALES_DATA + __description: Name of the shared Snowflake table. + db.namespace: + __context_names: + - outbound_shares + - inbound_shares + __example: DEV_DB + __description: Name of the database used to store shared data. + snowflake.grant.name: + __context_names: + - outbound_shares + __example: READ_ACCESS + __description: Name of the grant to a share. + snowflake.schema.name: + __context_names: + - inbound_shares + __example: PUBLIC + __description: Name of the schema where the table is located. + snowflake.share.name: + __context_names: + - outbound_shares + - inbound_shares + __example: SAMPLE_DATA + __description: Name of the share. event_timestamps: - snowflake.event.trigger: - __context_names: - - outbound_shares - - inbound_shares - __example: "snowflake.grant.created_on" - __description: Additionally to sending logs, each entry in `EVENT_TIMESTAMPS` is sent as event with key set to `snowflake.event.trigger`, value to key from `EVENT_TIMESTAMPS` and `timestamp` set to the key value. - snowflake.grant.created_on: - __context_names: - - outbound_shares - __example: 1639051180946000000 - __description: Timestamp of the date of creating the grant. - snowflake.share.created_on: - __context_names: - - outbound_shares - - inbound_shares - __example: 1639051180714000000 - __description: Timestamp of the date of creating the share. - snowflake.table.created_on: - __context_names: - - inbound_shares - __example: 1649940827875000000 - __description: Creation time of the table. - snowflake.table.ddl: - __context_names: - - inbound_shares - __example: 1639940327875000000 - __description: - Timestamp of the last DDL operation performed on the table or - view. - snowflake.table.update: - __context_names: - - inbound_shares - __example: 1649962827875000000 - __description: - Date and time the object was last altered by a DML, DDL, or background - metadata operation. + snowflake.event.trigger: + __context_names: + - outbound_shares + - inbound_shares + __example: "snowflake.grant.created_on" + __description: + Additionally to sending logs, each entry in `EVENT_TIMESTAMPS` is sent as event with key set to `snowflake.event.trigger`, value to + key from `EVENT_TIMESTAMPS` and `timestamp` set to the key value. + snowflake.grant.created_on: + __context_names: + - outbound_shares + __example: 1639051180946000000 + __description: Timestamp of the date of creating the grant. + snowflake.share.created_on: + __context_names: + - outbound_shares + - inbound_shares + __example: 1639051180714000000 + __description: Timestamp of the date of creating the share. + snowflake.table.created_on: + __context_names: + - inbound_shares + __example: 1649940827875000000 + __description: Creation time of the table. + snowflake.table.ddl: + __context_names: + - inbound_shares + __example: 1639940327875000000 + __description: Timestamp of the last DDL operation performed on the table or view. + snowflake.table.update: + __context_names: + - inbound_shares + __example: 1649962827875000000 + __description: Date and time the object was last altered by a DML, DDL, or background metadata operation. diff --git a/src/dtagent/plugins/shares.py b/src/dtagent/plugins/shares.py index 966dae2e..b93747b4 100644 --- a/src/dtagent/plugins/shares.py +++ b/src/dtagent/plugins/shares.py @@ -27,9 +27,9 @@ # # -import uuid from typing import Tuple, Dict from dtagent.plugins import Plugin +from dtagent.context import RUN_PLUGIN_KEY, RUN_RESULTS_KEY, RUN_ID_KEY # COMPILE_REMOVE ##endregion COMPILE_REMOVE @@ -41,14 +41,20 @@ class SharesPlugin(Plugin): Shares plugin class. """ - def process(self, run_proc: bool = True) -> Dict[str, Dict[str, int]]: + def process(self, run_id: str, run_proc: bool = True) -> Dict[str, Dict[str, int]]: """ Processes data for shares plugin. + + Args: + run_id (str): unique run identifier + run_proc (bool): indicator whether processing should be logged as completed + Returns: Dict[str,int]: A dictionary with telemetry counts for shares. Example: { + "dsoa.run.results": { "outbound_shares": { "entries": outbound_share_entries_cnt, "log_lines": outbound_share_logs_cnt, @@ -67,13 +73,14 @@ def process(self, run_proc: bool = True) -> Dict[str, Dict[str, int]]: "metrics": shares_metrics_cnt, "events": shares_events_cnt, }, + }, + "dsoa.run.id": "uuid_string" } """ t_outbound_shares = "APP.V_OUTBOUND_SHARE_TABLES" t_inbound_shares = "APP.V_INBOUND_SHARE_TABLES" t_share_events = "APP.V_SHARE_EVENTS" - run_id = str(uuid.uuid4().hex) if run_proc: # call to list inbound and outbound shares to temporary tables @@ -119,22 +126,26 @@ def process(self, run_proc: bool = True) -> Dict[str, Dict[str, int]]: ) return { - "outbound_shares": { - "entries": outbound_share_entries_cnt, - "log_lines": outbound_share_logs_cnt, - "metrics": outbound_share_metrics_cnt, - "events": outbound_share_events_cnt, - }, - "inbound_shares": { - "entries": inbound_share_entries_cnt, - "log_lines": inbound_share_logs_cnt, - "metrics": inbound_share_metrics_cnt, - "events": inbound_share_events_cnt, - }, - "shares": { - "entries": shares_entries_cnt, - "log_lines": shares_logs_cnt, - "metrics": shares_metrics_cnt, - "events": shares_events_cnt, + RUN_PLUGIN_KEY: "shares", + RUN_RESULTS_KEY: { + "outbound_shares": { + "entries": outbound_share_entries_cnt, + "log_lines": outbound_share_logs_cnt, + "metrics": outbound_share_metrics_cnt, + "events": outbound_share_events_cnt, + }, + "inbound_shares": { + "entries": inbound_share_entries_cnt, + "log_lines": inbound_share_logs_cnt, + "metrics": inbound_share_metrics_cnt, + "events": inbound_share_events_cnt, + }, + "shares": { + "entries": shares_entries_cnt, + "log_lines": shares_logs_cnt, + "metrics": shares_metrics_cnt, + "events": shares_events_cnt, + }, }, + RUN_ID_KEY: run_id, } diff --git a/src/dtagent/plugins/shares.sql/053_p_get_shares.sql b/src/dtagent/plugins/shares.sql/053_p_get_shares.sql index c7540289..8d3616e0 100644 --- a/src/dtagent/plugins/shares.sql/053_p_get_shares.sql +++ b/src/dtagent/plugins/shares.sql/053_p_get_shares.sql @@ -79,8 +79,7 @@ execute as caller as $$ DECLARE - q_get_shares TEXT DEFAULT 'SHOW SHARES;'; - q_pop_shares TEXT DEFAULT 'insert into DTAGENT_DB.APP.TMP_SHARES select * from table(result_scan(last_query_id()));'; + q_get_shares TEXT DEFAULT 'SHOW SHARES ->> insert into DTAGENT_DB.APP.TMP_SHARES select * from $1;'; tr_sh_table TEXT DEFAULT 'truncate table if exists DTAGENT_DB.APP.TMP_SHARES;'; tr_out_table TEXT DEFAULT 'truncate table if exists DTAGENT_DB.APP.TMP_OUTBOUND_SHARES;'; @@ -97,15 +96,13 @@ BEGIN EXECUTE IMMEDIATE :tr_in_table; EXECUTE IMMEDIATE :q_get_shares; - EXECUTE IMMEDIATE :q_pop_shares; - for share in c_shares do db_name := share.database_name; share_kind := share.kind; share_name := share.name; if (:share_kind = 'OUTBOUND') then - EXECUTE IMMEDIATE concat('show grants to share ', :share_name); + EXECUTE IMMEDIATE concat('SHOW GRANTS TO SHARE ', :share_name); insert into DTAGENT_DB.APP.TMP_OUTBOUND_SHARES select t.*, :share_name from table(result_scan(last_query_id())) t; diff --git a/src/dtagent/plugins/tasks.config/bom.yml b/src/dtagent/plugins/tasks.config/bom.yml index c2472709..768f49e9 100644 --- a/src/dtagent/plugins/tasks.config/bom.yml +++ b/src/dtagent/plugins/tasks.config/bom.yml @@ -19,4 +19,4 @@ references: privileges: SELECT - name: INFORMATION_SCHEMA.TASK_HISTORY() type: function - privileges: USAGE \ No newline at end of file + privileges: USAGE diff --git a/src/dtagent/plugins/tasks.config/instruments-def.yml b/src/dtagent/plugins/tasks.config/instruments-def.yml index 586a1116..fa224dc6 100644 --- a/src/dtagent/plugins/tasks.config/instruments-def.yml +++ b/src/dtagent/plugins/tasks.config/instruments-def.yml @@ -14,222 +14,222 @@ # * Copyright (c) 2024 Dynatrace LLC. All rights reserved. # * attributes: - db.query.text: - __context_names: - - task_versions - __example: SELECT * FROM users; - __description: The text of the query. - snowflake.database.id: - __context_names: - - serverless_tasks - - task_versions - __example: db123 - __description: The unique identifier for the database. - snowflake.error.code: - __context_names: - - task_history - __example: ERR123 - __description: The error code returned by the task. - snowflake.error.message: - __context_names: - - task_history - __example: Syntax error - __description: The error message returned by the task. - snowflake.query.hash: - __context_names: - - task_history - __example: hash123 - __description: The hash of the query. - snowflake.query.hash_version: - __context_names: - - task_history - __example: v1 - __description: The version of the query hash. - snowflake.query.id: - __context_names: - - task_history - __example: query123 - __description: The unique identifier for the query. - snowflake.query.parametrized_hash: - __context_names: - - task_history - __example: param_hash123 - __description: The parameterized hash of the query. - snowflake.query.parametrized_hash_version: - __context_names: - - task_history - __example: v1 - __description: The version of the parameterized query hash. - snowflake.schema.id: - __context_names: - - serverless_tasks - - task_versions - __example: schema123 - __description: The unique identifier for the schema. - snowflake.task.condition: - __context_names: - - task_versions - - task_history - __example: status = 'SUCCESS' - __description: The condition text of the task. - snowflake.task.config: - __context_names: - - task_history - __example: config123 - __description: The configuration of the task. - snowflake.task.config.allow_overlap: - __context_names: - - task_versions - __example: "true" - __description: Indicates if overlapping execution is allowed. - snowflake.task.end_time: - __context_names: - - serverless_tasks - __example: "1633046700000000000" - __description: The end time of the task. - snowflake.task.error_integration: - __context_names: - - task_versions - __example: error_integration123 - __description: The error integration for the task. - snowflake.task.graph.root_id: - __context_names: - - task_versions - - task_history - __example: root123 - __description: The root ID of the task graph. - snowflake.task.graph.version: - __context_names: - - task_versions - - task_history - __example: v1 - __description: The version of the task graph. - snowflake.task.id: - __context_names: - - serverless_tasks - - task_versions - __example: task123 - __description: The unique identifier for the task. - snowflake.task.instance_id: - __context_names: - - serverless_tasks - __example: instance123 - __description: The unique identifier for the task instance. - snowflake.task.last_committed_on: - __context_names: - - task_versions - __example: "1633046400000000000" - __description: The last committed time of the task. - snowflake.task.last_suspended_on: - __context_names: - - task_versions - __example: "1633046700000000000" - __description: The last suspended time of the task. - snowflake.task.owner: - __context_names: - - task_versions - __example: admin - __description: The owner of the task. - snowflake.task.predecessors: - __context_names: - - task_versions - __example: taskA, taskB - __description: The predecessors of the task. - snowflake.task.run.attempt: - __context_names: - - task_history - __example: "1" - __description: The attempt number of the task run. - snowflake.task.run.completed_time: - __context_names: - - task_history - __example: "1633046700000000000" - __description: The completed time of the task run. - snowflake.task.run.group_id: - __context_names: - - task_history - __example: group123 - __description: The group ID of the task run. - snowflake.task.run.id: - __context_names: - - task_history - __example: run123 - __description: The unique identifier for the task run. - snowflake.task.run.return_value: - __context_names: - - task_history - __example: "0" - __description: The return value of the task run. - snowflake.task.run.scheduled_time: - __context_names: - - task_history - __example: "1633046400000000000" - __description: The scheduled time of the task run. - snowflake.task.run.scheduled_from: - __context_names: - - task_history - __example: CRON - __description: The source from which the task was scheduled. - snowflake.task.run.state: - __context_names: - - task_history - __example: RUNNING - __description: The state of the task run. - snowflake.task.schedule: - __context_names: - - task_versions - __example: 0 0 * * * - __description: The schedule of the task. - snowflake.task.start_time: - __context_names: - - serverless_tasks - __example: "1633046400000000000" - __description: The start time of the task. + db.query.text: + __context_names: + - task_versions + __example: SELECT * FROM users; + __description: The text of the query. + snowflake.database.id: + __context_names: + - serverless_tasks + - task_versions + __example: db123 + __description: The unique identifier for the database. + snowflake.error.code: + __context_names: + - task_history + __example: ERR123 + __description: The error code returned by the task. + snowflake.error.message: + __context_names: + - task_history + __example: Syntax error + __description: The error message returned by the task. + snowflake.query.hash: + __context_names: + - task_history + __example: hash123 + __description: The hash of the query. + snowflake.query.hash_version: + __context_names: + - task_history + __example: v1 + __description: The version of the query hash. + snowflake.query.id: + __context_names: + - task_history + __example: query123 + __description: The unique identifier for the query. + snowflake.query.parametrized_hash: + __context_names: + - task_history + __example: param_hash123 + __description: The parameterized hash of the query. + snowflake.query.parametrized_hash_version: + __context_names: + - task_history + __example: v1 + __description: The version of the parameterized query hash. + snowflake.schema.id: + __context_names: + - serverless_tasks + - task_versions + __example: schema123 + __description: The unique identifier for the schema. + snowflake.task.condition: + __context_names: + - task_versions + - task_history + __example: status = 'SUCCESS' + __description: The condition text of the task. + snowflake.task.config: + __context_names: + - task_history + __example: config123 + __description: The configuration of the task. + snowflake.task.config.allow_overlap: + __context_names: + - task_versions + __example: "true" + __description: Indicates if overlapping execution is allowed. + snowflake.task.end_time: + __context_names: + - serverless_tasks + __example: "1633046700000000000" + __description: The end time of the task. + snowflake.task.error_integration: + __context_names: + - task_versions + __example: error_integration123 + __description: The error integration for the task. + snowflake.task.graph.root_id: + __context_names: + - task_versions + - task_history + __example: root123 + __description: The root ID of the task graph. + snowflake.task.graph.version: + __context_names: + - task_versions + - task_history + __example: v1 + __description: The version of the task graph. + snowflake.task.id: + __context_names: + - serverless_tasks + - task_versions + __example: task123 + __description: The unique identifier for the task. + snowflake.task.instance_id: + __context_names: + - serverless_tasks + __example: instance123 + __description: The unique identifier for the task instance. + snowflake.task.last_committed_on: + __context_names: + - task_versions + __example: "1633046400000000000" + __description: The last committed time of the task. + snowflake.task.last_suspended_on: + __context_names: + - task_versions + __example: "1633046700000000000" + __description: The last suspended time of the task. + snowflake.task.owner: + __context_names: + - task_versions + __example: admin + __description: The owner of the task. + snowflake.task.predecessors: + __context_names: + - task_versions + __example: taskA, taskB + __description: The predecessors of the task. + snowflake.task.run.attempt: + __context_names: + - task_history + __example: "1" + __description: The attempt number of the task run. + snowflake.task.run.completed_time: + __context_names: + - task_history + __example: "1633046700000000000" + __description: The completed time of the task run. + snowflake.task.run.group_id: + __context_names: + - task_history + __example: group123 + __description: The group ID of the task run. + snowflake.task.run.id: + __context_names: + - task_history + __example: run123 + __description: The unique identifier for the task run. + snowflake.task.run.return_value: + __context_names: + - task_history + __example: "0" + __description: The return value of the task run. + snowflake.task.run.scheduled_time: + __context_names: + - task_history + __example: "1633046400000000000" + __description: The scheduled time of the task run. + snowflake.task.run.scheduled_from: + __context_names: + - task_history + __example: CRON + __description: The source from which the task was scheduled. + snowflake.task.run.state: + __context_names: + - task_history + __example: RUNNING + __description: The state of the task run. + snowflake.task.schedule: + __context_names: + - task_versions + __example: 0 0 * * * + __description: The schedule of the task. + snowflake.task.start_time: + __context_names: + - serverless_tasks + __example: "1633046400000000000" + __description: The start time of the task. dimensions: - db.namespace: - __context_names: - - serverless_tasks - - task_versions - - task_history - __example: PROD_DB - __description: The name of the database. - snowflake.schema.name: - __context_names: - - serverless_tasks - - task_versions - - task_history - __example: public - __description: The name of the schema. - snowflake.task.name: - __context_names: - - serverless_tasks - - task_versions - - task_history - __example: daily_backup_task - __description: The name of the task. - snowflake.warehouse.name: - __context_names: - - task_versions - __example: COMPUTE_WH - __description: The name of the warehouse. + db.namespace: + __context_names: + - serverless_tasks + - task_versions + - task_history + __example: PROD_DB + __description: The name of the database. + snowflake.schema.name: + __context_names: + - serverless_tasks + - task_versions + - task_history + __example: public + __description: The name of the schema. + snowflake.task.name: + __context_names: + - serverless_tasks + - task_versions + - task_history + __example: daily_backup_task + __description: The name of the task. + snowflake.warehouse.name: + __context_names: + - task_versions + __example: COMPUTE_WH + __description: The name of the warehouse. event_timestamps: - snowflake.task.graph.version.created_on: - __context_names: - - task_versions - __example: "1633046400000000000" - __description: The creation time of the task graph version. - snowflake.event.trigger: - __context_names: - - task_versions - __example: "snowflake.task.graph.version.created_on" - __description: Additionally to sending logs, each entry in `EVENT_TIMESTAMPS` is sent as event with key set to `snowflake.event.trigger`, value to key from `EVENT_TIMESTAMPS` and `timestamp` set to the key value. + snowflake.task.graph.version.created_on: + __context_names: + - task_versions + __example: "1633046400000000000" + __description: The creation time of the task graph version. + snowflake.event.trigger: + __context_names: + - task_versions + __example: "snowflake.task.graph.version.created_on" + __description: + Additionally to sending logs, each entry in `EVENT_TIMESTAMPS` is sent as event with key set to `snowflake.event.trigger`, value to + key from `EVENT_TIMESTAMPS` and `timestamp` set to the key value. metrics: - snowflake.credits.used: - __context_names: - - serverless_tasks - __example: "10" - __description: - Number of credits billed for serverless task usage during the - START_TIME and END_TIME window. - displayName: Snowflake Credits Used - unit: credits + snowflake.credits.used: + __context_names: + - serverless_tasks + __example: "10" + __description: Number of credits billed for serverless task usage during the START_TIME and END_TIME window. + displayName: Snowflake Credits Used + unit: credits diff --git a/src/dtagent/plugins/tasks.py b/src/dtagent/plugins/tasks.py index e7a6682e..b17cd237 100644 --- a/src/dtagent/plugins/tasks.py +++ b/src/dtagent/plugins/tasks.py @@ -27,9 +27,9 @@ # # -import uuid from typing import Tuple, Dict -from src.dtagent.plugins import Plugin +from dtagent.plugins import Plugin +from dtagent.context import RUN_PLUGIN_KEY, RUN_RESULTS_KEY, RUN_ID_KEY # COMPILE_REMOVE ##endregion COMPILE_REMOVE @@ -41,14 +41,20 @@ class TasksPlugin(Plugin): Tasks plugin class. """ - def process(self, run_proc: bool = True) -> Dict[str, Dict[str, int]]: + def process(self, run_id: str, run_proc: bool = True) -> Dict[str, Dict[str, int]]: """ Processes the measures on serverless tasks, task history and task versions. + + Args: + run_id (str): unique run identifier + run_proc (bool): indicator whether processing should be logged as completed + Returns: Dict[str,int]: A dictionary with telemetry counts for tasks. Example: { + "dsoa.run.results": { "serverless_tasks": { "entries": serverless_tasks_entries_cnt, "log_lines": serverless_task_logs_cnt, @@ -67,6 +73,8 @@ def process(self, run_proc: bool = True) -> Dict[str, Dict[str, int]]: "metrics": task_history_metrics_cnt, "events": task_history_events_cnt, }, + }, + "dsoa.run.id": "uuid_string" } """ @@ -74,8 +82,6 @@ def process(self, run_proc: bool = True) -> Dict[str, Dict[str, int]]: t_task_hist = "APP.V_TASK_HISTORY" t_task_versions = "APP.V_TASK_VERSIONS" - run_id = str(uuid.uuid4().hex) - ( serverless_tasks_entries_cnt, serverless_task_logs_cnt, @@ -114,24 +120,28 @@ def process(self, run_proc: bool = True) -> Dict[str, Dict[str, int]]: ) return { - "serverless_tasks": { - "entries": serverless_tasks_entries_cnt, - "log_lines": serverless_task_logs_cnt, - "metrics": serverless_tasks_metrics_cnt, - "events": serverless_tasks_events_cnt, - }, - "task_versions": { - "entries": task_versions_entries_cnt, - "log_lines": task_versions_logs_cnt, - "metrics": task_versions_metrics_cnt, - "events": task_versions_events_cnt, - }, - "task_history": { - "entries": task_history_entries_cnt, - "log_lines": task_history_logs_cnt, - "metrics": task_history_metrics_cnt, - "events": task_history_events_cnt, + RUN_PLUGIN_KEY: "tasks", + RUN_RESULTS_KEY: { + "serverless_tasks": { + "entries": serverless_tasks_entries_cnt, + "log_lines": serverless_task_logs_cnt, + "metrics": serverless_tasks_metrics_cnt, + "events": serverless_tasks_events_cnt, + }, + "task_versions": { + "entries": task_versions_entries_cnt, + "log_lines": task_versions_logs_cnt, + "metrics": task_versions_metrics_cnt, + "events": task_versions_events_cnt, + }, + "task_history": { + "entries": task_history_entries_cnt, + "log_lines": task_history_logs_cnt, + "metrics": task_history_metrics_cnt, + "events": task_history_events_cnt, + }, }, + RUN_ID_KEY: run_id, } diff --git a/src/dtagent/plugins/trust_center.config/bom.yml b/src/dtagent/plugins/trust_center.config/bom.yml index 2e0f8162..2754d6bd 100644 --- a/src/dtagent/plugins/trust_center.config/bom.yml +++ b/src/dtagent/plugins/trust_center.config/bom.yml @@ -17,4 +17,3 @@ references: type: view privileges: SELECT granted to: DTAGENT_VIEWER - diff --git a/src/dtagent/plugins/trust_center.config/instruments-def.yml b/src/dtagent/plugins/trust_center.config/instruments-def.yml index 6d9b3c64..a1f08159 100644 --- a/src/dtagent/plugins/trust_center.config/instruments-def.yml +++ b/src/dtagent/plugins/trust_center.config/instruments-def.yml @@ -16,70 +16,58 @@ # * Catalog of instrumentation known to Dynatrace Snowflake Observability Agent - trust_center plugin attributes: - error.code: - __example: ERR001 - __description: The error code associated with the scanner, if any. - event.id: - __example: event123 - __description: A unique identifier for the security event. - event.kind: - __example: SECURITY_EVENT - __description: The kind of event, in this case, 'SECURITY_EVENT'. - snowflake.entity.details: - __example: Contains user data - __description: Additional details about the entity involved in the event. - snowflake.entity.id: - __example: entity123 - __description: The unique identifier for the entity involved in the event. - snowflake.entity.name: - __example: User Table - __description: The name of the entity involved in the event. - snowflake.entity.type: - __example: table - __description: - The type of entity involved in the event, such as a table, view, - or user. - snowflake.trust_center.scanner.name: - __example: 2.4 - __description: The name of the scanner used in the Trust Center. - snowflake.trust_center.scanner.description: - __example: Ensure monitoring and alerting exist for password sign-in without MFA - __description: A short description of the scanner used in the Trust Center. - snowflake.trust_center.scanner.package.name: - __example: CIS Package - __description: The name of the scanner package used in the Trust Center. - status.message: - __example: 2.4 Ensure monitoring and alerting exist for password sign-in without MFA - __description: - The name and description of the scanner, providing additional details about the - status. + error.code: + __example: ERR001 + __description: The error code associated with the scanner, if any. + event.id: + __example: event123 + __description: A unique identifier for the security event. + event.kind: + __example: SECURITY_EVENT + __description: The kind of event, in this case, 'SECURITY_EVENT'. + snowflake.entity.details: + __example: Contains user data + __description: Additional details about the entity involved in the event. + snowflake.entity.id: + __example: entity123 + __description: The unique identifier for the entity involved in the event. + snowflake.entity.name: + __example: User Table + __description: The name of the entity involved in the event. + snowflake.entity.type: + __example: table + __description: The type of entity involved in the event, such as a table, view, or user. + snowflake.trust_center.scanner.name: + __example: 2.4 + __description: The name of the scanner used in the Trust Center. + snowflake.trust_center.scanner.description: + __example: Ensure monitoring and alerting exist for password sign-in without MFA + __description: A short description of the scanner used in the Trust Center. + snowflake.trust_center.scanner.package.name: + __example: CIS Package + __description: The name of the scanner package used in the Trust Center. + status.message: + __example: 2.4 Ensure monitoring and alerting exist for password sign-in without MFA + __description: The name and description of the scanner, providing additional details about the status. dimensions: - event.category: - __example: Warning - __description: - The category of the event, such as 'Warning' or 'Vulnerability - management', based on the severity. - snowflake.trust_center.scanner.id: - __example: scanner123 - __description: The unique identifier for the scanner used in the Trust Center. - snowflake.trust_center.scanner.package.id: - __example: package123 - __description: - The unique identifier for the scanner package used in the Trust - Center. - snowflake.trust_center.scanner.type: - __example: CIS Benchmarks - __description: - The type of scanner used in the Trust Center, such as 'CIS Benchmarks' - or 'Threat Intelligence'. - vulnerability.risk.level: - __example: HIGH - __description: - The risk level of the vulnerability, such as LOW, MEDIUM, HIGH, - or CRITICAL. + event.category: + __example: Warning + __description: The category of the event, such as 'Warning' or 'Vulnerability management', based on the severity. + snowflake.trust_center.scanner.id: + __example: scanner123 + __description: The unique identifier for the scanner used in the Trust Center. + snowflake.trust_center.scanner.package.id: + __example: package123 + __description: The unique identifier for the scanner package used in the Trust Center. + snowflake.trust_center.scanner.type: + __example: CIS Benchmarks + __description: The type of scanner used in the Trust Center, such as 'CIS Benchmarks' or 'Threat Intelligence'. + vulnerability.risk.level: + __example: HIGH + __description: The risk level of the vulnerability, such as LOW, MEDIUM, HIGH, or CRITICAL. metrics: - snowflake.trust_center.findings: - __example: "10" - __description: The total number of findings at risk identified by the scanner. - displayName: Trust Center Findings Count - unit: count + snowflake.trust_center.findings: + __example: "10" + __description: The total number of findings at risk identified by the scanner. + displayName: Trust Center Findings Count + unit: count diff --git a/src/dtagent/plugins/trust_center.py b/src/dtagent/plugins/trust_center.py index dfb72e55..cb9656a3 100644 --- a/src/dtagent/plugins/trust_center.py +++ b/src/dtagent/plugins/trust_center.py @@ -26,12 +26,12 @@ # SOFTWARE. # # -import uuid import logging from dtagent.otel.events import EventType from dtagent.plugins import Plugin from dtagent.util import _unpack_json_dict from typing import Tuple, Dict +from dtagent.context import RUN_PLUGIN_KEY, RUN_RESULTS_KEY, RUN_ID_KEY # COMPILE_REMOVE ##endregion COMPILE_REMOVE @@ -77,25 +77,31 @@ def _prepare_event_payload_critical_risk(self, row_dict: dict) -> Tuple[EventTyp return EventType.CUSTOM_ALERT, "Trust Center Critical problem", {} - def process(self, run_proc: bool = True) -> Dict[str, Dict[str, int]]: + def process(self, run_id: str, run_proc: bool = True) -> Dict[str, Dict[str, int]]: """ Processes data for trust center plugin. - Returns + + Args: + run_id (str): unique run identifier + run_proc (bool): indicator whether processing should be logged as completed + + Returns: Dict[str,int]: A dictionary with counts of processed telemetry data. Example: { + "dsoa.run.results": { "trust_center": { "entries": entries_cnt, "log_lines": logs_cnt, "metrics": metrics_cnt, "events": events_cnt } + }, + "dsoa.run.id": "uuid_string" } """ - run_id = str(uuid.uuid4().hex) - metric_entries_cnt, _, metrics_sent_cnt, _ = self._log_entries( f_entry_generator=lambda: self._get_table_rows("APP.V_TRUST_CENTER_METRICS"), context_name="trust_center", @@ -130,14 +136,9 @@ def process(self, run_proc: bool = True) -> Dict[str, Dict[str, int]]: } if run_proc: - self._report_execution( - "trust_center", - str(self.processed_last_timestamp), - None, - results_dict, - ) - - return results_dict + self._report_execution("trust_center", str(self.processed_last_timestamp), None, results_dict, run_id=run_id) + + return {RUN_PLUGIN_KEY: "trust_center", RUN_RESULTS_KEY: results_dict, RUN_ID_KEY: run_id} ##endregion diff --git a/src/dtagent/plugins/users.config/instruments-def.yml b/src/dtagent/plugins/users.config/instruments-def.yml index c3080649..73364439 100644 --- a/src/dtagent/plugins/users.config/instruments-def.yml +++ b/src/dtagent/plugins/users.config/instruments-def.yml @@ -16,115 +16,118 @@ # * Catalog of instrumentation known to Dynatrace Snowflake Observability Agent - users plugin attributes: - snowflake.user.bypass_mfa_until: - __example: "2024-11-06T00:00:00Z" - __description: The time until which the user can bypass MFA. - snowflake.user.comment: - __example: New user account - __description: Any comments associated with the user. - snowflake.user.default.namespace: - __example: PUBLIC - __description: The default namespace for the user. - snowflake.user.default.role: - __example: SYSADMIN - __description: The default role for the user. - snowflake.user.default.secondary_role: - __example: SECURITYADMIN - __description: The default secondary role for the user. - snowflake.user.default.warehouse: - __example: COMPUTE_WH - __description: The default warehouse for the user. - snowflake.user.display_name: - __example: John Doe - __description: The display name of the user. - snowflake.user.email: - __example: jdoe@example.com - __description: The email address of the user. - snowflake.user.expires_at: - __example: "1620213179885000000" - __description: The expiration date of the user account. - snowflake.user.ext_authn.duo: - __example: "true" - __description: Indicates if Duo authentication is enabled for the user. - snowflake.user.ext_authn.uid: - __example: ext123 - __description: The external authentication UID for the user. - snowflake.user.has_password: - __example: "true" - __description: Indicates if the user has a password set. - snowflake.user.id: - __example: "12345" - __description: The unique identifier for the user. - snowflake.user.is_disabled: - __example: "false" - __description: Indicates if the user account is disabled. - snowflake.user.is_locked: - __example: "false" - __description: Indicates if the user account is locked by Snowflake. - snowflake.user.locked_until_time: - __example: "1615479617866000000" - __description: The time until which the user account is locked. - snowflake.user.must_change_password: - __example: "true" - __description: Indicates if the user must change their password. - snowflake.user.name: - __example: jdoe - __description: The login name of the user. - snowflake.user.name.first: - __example: John - __description: The first name of the user. - snowflake.user.name.last: - __example: Doe - __description: The last name of the user. - snowflake.user.owner: - __example: ACCOUNTADMIN - __description: The role that owns the user account. - snowflake.user.type: - __example: LEGACY_SERVICE - __description: Specifies the type of user - snowflake.user.created_on: - __example: "1651830381846000000" - __description: The creation time of the user account. - snowflake.user.deleted_on: - __example: "1615219846384000000" - __description: The deletion time of the user account, if applicable. - snowflake.user.last_success_login: - __example: "1732181350954000000" - __description: The last successful login time of the user. - snowflake.user.password_last_set_time: - __example: "1615219848053000000" - __description: The last time the user's password was set. - snowflake.user.privilege: - __example: "CREATE SERVICE:SCHEMA" - __description: Name of the privilege and type of object this privilege granted on to the user or role. Composed as `privilege:granted_on_object`. - snowflake.user.privilege.grants_on: - __example: ["TRUST_CENTER_ADMIN", "COMPUTE_WH"] - __description: List of all objects of given type on which given privilege was given; both object type and privilege are reported as `snowflake.user.privilege` - snowflake.user.privilege.granted_by: - __example: ["ACCOUNTADMIN"] - __description: Array of all roles which granted grants to a user for a privilege. - snowflake.user.roles.last_altered: - __example: "1718260900411000000" - __description: Nanosecond timestamp of last alteration of roles granted to user. - snowflake.user.roles.all: - __example: "SNOWFLAKE_FINANCE,MONITORING" - __description: Comma separated list of all roles granted to a user. - snowflake.user.roles.granted_by: - __example: ["DEMIGOD", "SECURITYADMIN", "ACCOUNTADMIN"] - __description: Array of admin roles that were used to grant current list of user roles. - snowflake.user.roles.direct: - __example: ["DEVOPS_ROLE", "SYSADMIN", "ACCOUNTADMIN"] - __description: List of all direct roles granted to user. - snowflake.user.privilege.last_altered: - __example: "1732181350954000000" - __description: Nanosecond timestamp of the last alteration to user's privileges. - snowflake.user.roles.direct.removed: - __example: "ACCOUNTADMIN" - __description: Name of the role that was revoked from user. - snowflake.user.roles.direct.removed_on: - __example: "1718260900411000000" - __description: Nanosecond timestamp of the last deletion of a direct role to a user. + snowflake.user.bypass_mfa_until: + __example: "2024-11-06T00:00:00Z" + __description: The time until which the user can bypass MFA. + snowflake.user.comment: + __example: New user account + __description: Any comments associated with the user. + snowflake.user.default.namespace: + __example: PUBLIC + __description: The default namespace for the user. + snowflake.user.default.role: + __example: SYSADMIN + __description: The default role for the user. + snowflake.user.default.secondary_role: + __example: SECURITYADMIN + __description: The default secondary role for the user. + snowflake.user.default.warehouse: + __example: COMPUTE_WH + __description: The default warehouse for the user. + snowflake.user.display_name: + __example: John Doe + __description: The display name of the user. + snowflake.user.email: + __example: jdoe@example.com + __description: The email address of the user. + snowflake.user.expires_at: + __example: "1620213179885000000" + __description: The expiration date of the user account. + snowflake.user.ext_authn.duo: + __example: "true" + __description: Indicates if Duo authentication is enabled for the user. + snowflake.user.ext_authn.uid: + __example: ext123 + __description: The external authentication UID for the user. + snowflake.user.has_password: + __example: "true" + __description: Indicates if the user has a password set. + snowflake.user.id: + __example: "12345" + __description: The unique identifier for the user. + snowflake.user.is_disabled: + __example: "false" + __description: Indicates if the user account is disabled. + snowflake.user.is_locked: + __example: "false" + __description: Indicates if the user account is locked by Snowflake. + snowflake.user.locked_until_time: + __example: "1615479617866000000" + __description: The time until which the user account is locked. + snowflake.user.must_change_password: + __example: "true" + __description: Indicates if the user must change their password. + snowflake.user.name: + __example: jdoe + __description: The login name of the user. + snowflake.user.name.first: + __example: John + __description: The first name of the user. + snowflake.user.name.last: + __example: Doe + __description: The last name of the user. + snowflake.user.owner: + __example: ACCOUNTADMIN + __description: The role that owns the user account. + snowflake.user.type: + __example: LEGACY_SERVICE + __description: Specifies the type of user + snowflake.user.created_on: + __example: "1651830381846000000" + __description: The creation time of the user account. + snowflake.user.deleted_on: + __example: "1615219846384000000" + __description: The deletion time of the user account, if applicable. + snowflake.user.last_success_login: + __example: "1732181350954000000" + __description: The last successful login time of the user. + snowflake.user.password_last_set_time: + __example: "1615219848053000000" + __description: The last time the user's password was set. + snowflake.user.privilege: + __example: "CREATE SERVICE:SCHEMA" + __description: + Name of the privilege and type of object this privilege granted on to the user or role. Composed as `privilege:granted_on_object`. + snowflake.user.privilege.grants_on: + __example: ["TRUST_CENTER_ADMIN", "COMPUTE_WH"] + __description: + List of all objects of given type on which given privilege was given; both object type and privilege are reported as + `snowflake.user.privilege` + snowflake.user.privilege.granted_by: + __example: ["ACCOUNTADMIN"] + __description: Array of all roles which granted grants to a user for a privilege. + snowflake.user.roles.last_altered: + __example: "1718260900411000000" + __description: Nanosecond timestamp of last alteration of roles granted to user. + snowflake.user.roles.all: + __example: "SNOWFLAKE_FINANCE,MONITORING" + __description: Comma separated list of all roles granted to a user. + snowflake.user.roles.granted_by: + __example: ["DEMIGOD", "SECURITYADMIN", "ACCOUNTADMIN"] + __description: Array of admin roles that were used to grant current list of user roles. + snowflake.user.roles.direct: + __example: ["DEVOPS_ROLE", "SYSADMIN", "ACCOUNTADMIN"] + __description: List of all direct roles granted to user. + snowflake.user.privilege.last_altered: + __example: "1732181350954000000" + __description: Nanosecond timestamp of the last alteration to user's privileges. + snowflake.user.roles.direct.removed: + __example: "ACCOUNTADMIN" + __description: Name of the role that was revoked from user. + snowflake.user.roles.direct.removed_on: + __example: "1718260900411000000" + __description: Nanosecond timestamp of the last deletion of a direct role to a user. dimensions: - db.user: - __example: admin - __description: Snowflake user who issued the query. + db.user: + __example: admin + __description: Snowflake user who issued the query. diff --git a/src/dtagent/plugins/users.py b/src/dtagent/plugins/users.py index 561f0049..bdb1e965 100644 --- a/src/dtagent/plugins/users.py +++ b/src/dtagent/plugins/users.py @@ -27,10 +27,10 @@ # # -import uuid from typing import Tuple, Dict from snowflake.snowpark.functions import current_timestamp from dtagent.plugins import Plugin +from dtagent.context import RUN_PLUGIN_KEY, RUN_RESULTS_KEY, RUN_ID_KEY # COMPILE_REMOVE ##endregion COMPILE_REMOVE @@ -48,14 +48,20 @@ class UsersPlugin(Plugin): Users plugin class. """ - def process(self, run_proc: bool = True) -> Dict[str, Dict[str, int]]: + def process(self, run_id: str, run_proc: bool = True) -> Dict[str, Dict[str, int]]: """ Processes data for users plugin. + + Args: + run_id (str): unique run identifier + run_proc (bool): indicator whether processing should be logged as completed + Returns: Dict[str,int]: A dictionary with telemetry counts for users. Example: { + "dsoa.run.results": { "users": { "entries": entries_cnt, "log_lines": logs_cnt, @@ -69,12 +75,13 @@ def process(self, run_proc: bool = True) -> Dict[str, Dict[str, int]]: "events": events_cnt, }, ... + }, + "dsoa.run.id": "uuid_string" } """ modes = self._configuration.get(plugin_name="users", key="roles_monitoring_mode", default_value=[]) processed_entries_cnt = 0 - run_id = str(uuid.uuid4().hex) views_list = ["APP.V_USERS_INSTRUMENTED"] @@ -105,9 +112,9 @@ def process(self, run_proc: bool = True) -> Dict[str, Dict[str, int]]: processed_entries_cnt += entries_cnt if run_proc: - self._report_execution("users", current_timestamp() if processed_entries_cnt > 0 else None, None, results_dict) + self._report_execution("users", current_timestamp() if processed_entries_cnt > 0 else None, None, results_dict, run_id=run_id) - return results_dict + return {RUN_PLUGIN_KEY: "users", RUN_RESULTS_KEY: results_dict, RUN_ID_KEY: run_id} ##endregion diff --git a/src/dtagent/plugins/warehouse_usage.config/bom.yml b/src/dtagent/plugins/warehouse_usage.config/bom.yml index 6d7d137d..2033306b 100644 --- a/src/dtagent/plugins/warehouse_usage.config/bom.yml +++ b/src/dtagent/plugins/warehouse_usage.config/bom.yml @@ -17,6 +17,6 @@ references: - name: SNOWFLAKE.ACCOUNT_USAGE.WAREHOUSE_LOAD_HISTORY type: view privileges: SELECT - - name: SNOWFLAKE.ACCOUNT_USAGE.WAREHOUSE_METERING_HISTORY + - name: SNOWFLAKE.ACCOUNT_USAGE.WAREHOUSE_METERING_HISTORY type: view - privileges: SELECT \ No newline at end of file + privileges: SELECT diff --git a/src/dtagent/plugins/warehouse_usage.config/instruments-def.yml b/src/dtagent/plugins/warehouse_usage.config/instruments-def.yml index c888b614..9075d787 100644 --- a/src/dtagent/plugins/warehouse_usage.config/instruments-def.yml +++ b/src/dtagent/plugins/warehouse_usage.config/instruments-def.yml @@ -15,113 +15,113 @@ # * attributes: - db.user: - __context_names: - - warehouse_usage - __example: admin - __description: The user who initiated the event. - snowflake.query.id: - __context_names: - - warehouse_usage - __example: query123 - __description: The unique identifier for the query associated with the event. - snowflake.role.name: - __context_names: - - warehouse_usage - __example: SYSADMIN - __description: The role name associated with the event. - snowflake.warehouse.cluster.number: - __context_names: - - warehouse_usage - __example: "1" - __description: The number of the cluster within the warehouse. - snowflake.warehouse.clusters.count: - __context_names: - - warehouse_usage - __example: "2" - __description: The number of clusters in the warehouse. - snowflake.warehouse.event.reason: - __context_names: - - warehouse_usage - __example: USER_REQUEST - __description: The reason for the event. - snowflake.warehouse.id: - __context_names: - - warehouse_usage - - warehouse_usage_load - - warehouse_usage_metering - __example: wh123 - __description: The unique identifier for the warehouse. - snowflake.warehouse.size: - __context_names: - - warehouse_usage - __example: X-SMALL - __description: The size of the warehouse. + db.user: + __context_names: + - warehouse_usage + __example: admin + __description: The user who initiated the event. + snowflake.query.id: + __context_names: + - warehouse_usage + __example: query123 + __description: The unique identifier for the query associated with the event. + snowflake.role.name: + __context_names: + - warehouse_usage + __example: SYSADMIN + __description: The role name associated with the event. + snowflake.warehouse.cluster.number: + __context_names: + - warehouse_usage + __example: "1" + __description: The number of the cluster within the warehouse. + snowflake.warehouse.clusters.count: + __context_names: + - warehouse_usage + __example: "2" + __description: The number of clusters in the warehouse. + snowflake.warehouse.event.reason: + __context_names: + - warehouse_usage + __example: USER_REQUEST + __description: The reason for the event. + snowflake.warehouse.id: + __context_names: + - warehouse_usage + - warehouse_usage_load + - warehouse_usage_metering + __example: wh123 + __description: The unique identifier for the warehouse. + snowflake.warehouse.size: + __context_names: + - warehouse_usage + __example: X-SMALL + __description: The size of the warehouse. dimensions: - snowflake.warehouse.event.name: - __context_names: - - warehouse_usage - __example: WAREHOUSE_START - __description: The name of the event. - snowflake.warehouse.event.state: - __context_names: - - warehouse_usage - __example: STARTED - __description: The state of the event, such as STARTED or COMPLETED. - snowflake.warehouse.name: - __context_names: - - warehouse_usage - - warehouse_usage_load - - warehouse_usage_metering - __example: COMPUTE_WH - __description: The name of the warehouse. + snowflake.warehouse.event.name: + __context_names: + - warehouse_usage + __example: WAREHOUSE_START + __description: The name of the event. + snowflake.warehouse.event.state: + __context_names: + - warehouse_usage + __example: STARTED + __description: The state of the event, such as STARTED or COMPLETED. + snowflake.warehouse.name: + __context_names: + - warehouse_usage + - warehouse_usage_load + - warehouse_usage_metering + __example: COMPUTE_WH + __description: The name of the warehouse. metrics: - snowflake.credits.cloud_services: - __context_names: - - warehouse_usage_metering - __example: "2" - __description: The number of credits used for cloud services. - displayName: Cloud Services Credits Used - unit: credits - snowflake.credits.compute: - __context_names: - - warehouse_usage_metering - __example: "8" - __description: The number of credits used for compute. - displayName: Compute Credits Used - unit: credits - snowflake.credits.used: - __context_names: - - warehouse_usage_metering - __example: "10" - __description: The total number of credits used by the warehouse. - displayName: Snowflake Credits Used - unit: credits - snowflake.load.blocked: - __context_names: - - warehouse_usage_load - __example: "0" - __description: The average number of queries blocked by a transaction lock. - displayName: Average Blocked Queries - unit: count - snowflake.load.queued.overloaded: - __context_names: - - warehouse_usage_load - __example: "2" - __description: The average number of queries queued due to load. - displayName: Average Queued Queries (Load) - unit: count - snowflake.load.queued.provisioning: - __context_names: - - warehouse_usage_load - __example: "1" - __description: The average number of queries queued due to provisioning. - displayName: Average Queued Queries (Provisioning) - unit: count - snowflake.load.running: - __context_names: - - warehouse_usage_load - __example: "5" - __description: The average number of running queries. - displayName: Average Running Queries - unit: count + snowflake.credits.cloud_services: + __context_names: + - warehouse_usage_metering + __example: "2" + __description: The number of credits used for cloud services. + displayName: Cloud Services Credits Used + unit: credits + snowflake.credits.compute: + __context_names: + - warehouse_usage_metering + __example: "8" + __description: The number of credits used for compute. + displayName: Compute Credits Used + unit: credits + snowflake.credits.used: + __context_names: + - warehouse_usage_metering + __example: "10" + __description: The total number of credits used by the warehouse. + displayName: Snowflake Credits Used + unit: credits + snowflake.load.blocked: + __context_names: + - warehouse_usage_load + __example: "0" + __description: The average number of queries blocked by a transaction lock. + displayName: Average Blocked Queries + unit: count + snowflake.load.queued.overloaded: + __context_names: + - warehouse_usage_load + __example: "2" + __description: The average number of queries queued due to load. + displayName: Average Queued Queries (Load) + unit: count + snowflake.load.queued.provisioning: + __context_names: + - warehouse_usage_load + __example: "1" + __description: The average number of queries queued due to provisioning. + displayName: Average Queued Queries (Provisioning) + unit: count + snowflake.load.running: + __context_names: + - warehouse_usage_load + __example: "5" + __description: The average number of running queries. + displayName: Average Running Queries + unit: count diff --git a/src/dtagent/plugins/warehouse_usage.py b/src/dtagent/plugins/warehouse_usage.py index a7f18652..69d3c0d7 100644 --- a/src/dtagent/plugins/warehouse_usage.py +++ b/src/dtagent/plugins/warehouse_usage.py @@ -27,9 +27,9 @@ # # -import uuid from typing import Tuple, Dict -from src.dtagent.plugins import Plugin +from dtagent.plugins import Plugin +from dtagent.context import RUN_PLUGIN_KEY, RUN_RESULTS_KEY, RUN_ID_KEY # COMPILE_REMOVE ##endregion COMPILE_REMOVE @@ -41,14 +41,20 @@ class WarehouseUsagePlugin(Plugin): Warehouse usage plugin class. """ - def process(self, run_proc: bool = True) -> Dict[str, Dict[str, int]]: + def process(self, run_id: str, run_proc: bool = True) -> Dict[str, Dict[str, int]]: """ Processes data for warehouse usage plugin. + + Args: + run_id (str): unique run identifier + run_proc (bool): indicator whether processing should be logged as completed + Returns: Dict[str,int]: A dictionary with telemetry counts for warehouse usage. Example: { + "dsoa.run.results": { "warehouse_usage": { "entries": entries_wh_events_cnt, "log_lines": logs_wh_events_cnt, @@ -67,6 +73,8 @@ def process(self, run_proc: bool = True) -> Dict[str, Dict[str, int]]: "metrics": metrics_wh_metering_cnt, "events": events_wh_metering_cnt, }, + }, + "dsoa.run.id": "uuid_string" } """ @@ -74,8 +82,6 @@ def process(self, run_proc: bool = True) -> Dict[str, Dict[str, int]]: t_wh_load_hist = "APP.V_WAREHOUSE_LOAD_HISTORY" t_wh_metering_hist = "APP.V_WAREHOUSE_METERING_HISTORY" - run_id = str(uuid.uuid4().hex) - entries_wh_events_cnt, logs_wh_events_cnt, metrics_wh_events_cnt, events_wh_events_cnt = self._log_entries( lambda: self._get_table_rows(t_wh_events), "warehouse_usage", @@ -98,22 +104,26 @@ def process(self, run_proc: bool = True) -> Dict[str, Dict[str, int]]: ) return { - "warehouse_usage": { - "entries": entries_wh_events_cnt, - "log_lines": logs_wh_events_cnt, - "metrics": metrics_wh_events_cnt, - "events": events_wh_events_cnt, - }, - "warehouse_usage_load": { - "entries": entries_wh_load_cnt, - "log_lines": logs_wh_load_cnt, - "metrics": metrics_wh_load_cnt, - "events": events_wh_load_cnt, - }, - "warehouse_usage_metering": { - "entries": entries_wh_metering_cnt, - "log_lines": logs_wh_metering_cnt, - "metrics": metrics_wh_metering_cnt, - "events": events_wh_metering_cnt, + RUN_PLUGIN_KEY: "warehouse_usage", + RUN_RESULTS_KEY: { + "warehouse_usage": { + "entries": entries_wh_events_cnt, + "log_lines": logs_wh_events_cnt, + "metrics": metrics_wh_events_cnt, + "events": events_wh_events_cnt, + }, + "warehouse_usage_load": { + "entries": entries_wh_load_cnt, + "log_lines": logs_wh_load_cnt, + "metrics": metrics_wh_load_cnt, + "events": events_wh_load_cnt, + }, + "warehouse_usage_metering": { + "entries": entries_wh_metering_cnt, + "log_lines": logs_wh_metering_cnt, + "metrics": metrics_wh_metering_cnt, + "events": events_wh_metering_cnt, + }, }, + RUN_ID_KEY: run_id, } diff --git a/test/__init__.py b/test/__init__.py index b324bfa1..f1aa7cf5 100644 --- a/test/__init__.py +++ b/test/__init__.py @@ -119,7 +119,8 @@ def process( OtelManager.reset_current_fail_count() if is_local_testing(): - mock_client = MockTelemetryClient(sources[0] if sources else None) + source_name = sources[0] if sources else None + mock_client = MockTelemetryClient(source_name) with mock_client.mock_telemetry_sending(): import time diff --git a/test/_mocks/telemetry.py b/test/_mocks/telemetry.py index 766032be..c3c6ef70 100644 --- a/test/_mocks/telemetry.py +++ b/test/_mocks/telemetry.py @@ -31,6 +31,8 @@ from git import Union +from dtagent.context import RUN_ID_KEY, RUN_RESULTS_KEY + class MockTelemetryClient: @@ -100,6 +102,13 @@ def sort_key(item): expected_str.splitlines(), actual_str.splitlines(), fromfile="expected", tofile="actual", lineterm="" ) ) + if telemetry_type == "biz_events": + if isinstance(sorted_actual, list): + for entry in sorted_actual: + entry["data"].pop(RUN_RESULTS_KEY, None) + else: + sorted_actual["data"].pop(RUN_RESULTS_KEY, None) + assert ( sorted_actual == sorted_expected ), f"Telemetry type {telemetry_type} does not match expected results from {filepath}:\n\nDiff:\n{diff}" @@ -390,7 +399,8 @@ def __cleanup_telemetry_dict(data_dict: Dict[str, Any]) -> Dict[str, Any]: # id in biz events and events is unique per event "id", # each agent run has a different run id - "dsoa.run.id", + RUN_ID_KEY, + RUN_RESULTS_KEY, "dsoa.task.exec.id", # DSOA versions "app.version", diff --git a/test/_utils.py b/test/_utils.py index 19433a34..7a3d1847 100644 --- a/test/_utils.py +++ b/test/_utils.py @@ -23,6 +23,7 @@ # import os import sys +import uuid import datetime from typing import Any, Generator, Dict, List, Optional, Callable, Tuple import logging @@ -209,12 +210,12 @@ def _merge_pickles_from_tests() -> Dict[str, str]: class LocalTelemetrySender(TelemetrySender): PICKLES = _merge_pickles_from_tests() - def __init__(self, session: snowpark.Session, params: dict, limit_results: int = 2, config: TestConfiguration = None): + def __init__(self, session: snowpark.Session, params: dict, exec_id: str, limit_results: int = 2, config: TestConfiguration = None): self._local_config = config self.limit_results = limit_results - TelemetrySender.__init__(self, session, params) + TelemetrySender.__init__(self, session, params, exec_id) self._configuration.get_last_measurement_update = lambda *args, **kwargs: datetime.datetime.fromtimestamp( 0, tz=datetime.timezone.utc @@ -244,7 +245,7 @@ def telemetry_test_sender( config._config["otel"]["spans"]["max_export_batch_size"] = 1 config._config["otel"]["logs"]["max_export_batch_size"] = 1 - sender = LocalTelemetrySender(session, params, limit_results=limit_results, config=config) + sender = LocalTelemetrySender(session, params, limit_results=limit_results, config=config, exec_id=str(uuid.uuid4().hex)) mock_client = MockTelemetryClient(test_source) with mock_client.mock_telemetry_sending(): @@ -276,6 +277,7 @@ def execute_telemetry_test( metrics_at_least: Whether metrics should be at least or exactly the expected """ from test import _get_session + from dtagent.context import RUN_ID_KEY, RUN_RESULTS_KEY affecting_types_for_entries = affecting_types_for_entries or ["logs", "metrics", "spans"] @@ -295,9 +297,10 @@ def execute_telemetry_test( ) assert test_name in results + assert RUN_RESULTS_KEY in results[test_name] for plugin_key in base_count.keys(): - assert plugin_key in results[test_name] + assert plugin_key in results[test_name][RUN_RESULTS_KEY] logs_expected = base_count[plugin_key].get("log_lines", 0) if "logs" not in disabled_telemetry else 0 spans_expected = base_count[plugin_key].get("spans", 0) if "spans" not in disabled_telemetry else 0 @@ -307,11 +310,11 @@ def execute_telemetry_test( base_count[plugin_key].get("entries", 0) if (logs_expected + spans_expected + metrics_expected + events_expected > 0) else 0 ) - assert results[test_name][plugin_key].get("entries", 0) == entries_expected - assert results[test_name][plugin_key].get("log_lines", 0) == logs_expected - assert results[test_name][plugin_key].get("spans", 0) == spans_expected - assert results[test_name][plugin_key].get("metrics", 0) == metrics_expected - assert results[test_name][plugin_key].get("events", 0) == events_expected + assert results[test_name][RUN_RESULTS_KEY][plugin_key].get("entries", 0) == entries_expected + assert results[test_name][RUN_RESULTS_KEY][plugin_key].get("log_lines", 0) == logs_expected + assert results[test_name][RUN_RESULTS_KEY][plugin_key].get("spans", 0) == spans_expected + assert results[test_name][RUN_RESULTS_KEY][plugin_key].get("metrics", 0) == metrics_expected + assert results[test_name][RUN_RESULTS_KEY][plugin_key].get("events", 0) == events_expected def get_config(pickle_conf: str = None) -> TestConfiguration: diff --git a/test/core/test_connector.py b/test/core/test_connector.py index b8e8be17..0bc78338 100644 --- a/test/core/test_connector.py +++ b/test/core/test_connector.py @@ -22,11 +22,13 @@ # SOFTWARE. # # - +import uuid import logging from unittest.mock import patch +from dtagent import context from dtagent.util import get_now_timestamp, get_now_timestamp_formatted +from dtagent.context import RUN_ID_KEY, RUN_RESULTS_KEY from test import _get_session, _utils from test._utils import LocalTelemetrySender, read_clean_json_from_file, telemetry_test_sender from test._mocks.telemetry import MockTelemetryClient @@ -63,19 +65,23 @@ def test_viewsend(self): # ): rows_cnt = random.randint(10, 20) session = _get_session() + context_name = "test_viewsend" results = telemetry_test_sender( session, "APP.V_EVENT_LOG", - {"auto_mode": False, "context": "test_viewsend", "logs": True, "events": True, "bizevents": True, "davis_events": True}, + {"auto_mode": False, "context": context_name, "logs": True, "events": True, "bizevents": True, "davis_events": True}, limit_results=rows_cnt, config=_utils.get_config(), ) - assert results["entries"] == rows_cnt # all - assert results["log_lines"] == rows_cnt # logs - assert results["events"] == rows_cnt # events - assert results["biz_events"] == rows_cnt # biz_events - assert results["davis_events"] == rows_cnt # davis_events + assert RUN_RESULTS_KEY in results + assert context_name in results[RUN_RESULTS_KEY] + assert RUN_ID_KEY in results + assert results[RUN_RESULTS_KEY][context_name]["entries"] == rows_cnt # all + assert results[RUN_RESULTS_KEY][context_name]["log_lines"] == rows_cnt # logs + assert results[RUN_RESULTS_KEY][context_name]["events"] == rows_cnt # events + assert results[RUN_RESULTS_KEY][context_name]["biz_events"] == rows_cnt # biz_events + assert results[RUN_RESULTS_KEY][context_name]["davis_events"] == rows_cnt # davis_events @pytest.mark.xdist_group(name="test_telemetry") def test_large_view_send_as_be(self): @@ -86,22 +92,27 @@ def test_large_view_send_as_be(self): LOG.debug("We will send %s rows as BizEvents", rows_cnt) session = _get_session() + context_name = "test_large_view_send_as_be" results = telemetry_test_sender( session, "APP.V_EVENT_LOG", - {"auto_mode": False, "context": "test_large_view_send_as_be", "logs": False, "events": False, "bizevents": True}, + {"auto_mode": False, "context": context_name, "logs": False, "events": False, "bizevents": True}, limit_results=rows_cnt, config=_utils.get_config(), test_source=None, # we don to record tests with variable data size ) - LOG.debug("We have sent %d rows as BizEvents", results["biz_events"]) + assert RUN_RESULTS_KEY in results + assert context_name in results[RUN_RESULTS_KEY] + + LOG.debug("We have sent %d rows as BizEvents", results[RUN_RESULTS_KEY][context_name]["biz_events"]) - assert results["entries"] == rows_cnt # all - assert results["log_lines"] == 0 # logs - assert results["events"] == 0 # events - assert results["biz_events"] == rows_cnt # bizevents - assert results["davis_events"] == 0 # davis_events + assert RUN_ID_KEY in results + assert results[RUN_RESULTS_KEY][context_name]["entries"] == rows_cnt # all + assert results[RUN_RESULTS_KEY][context_name]["log_lines"] == 0 # logs + assert results[RUN_RESULTS_KEY][context_name]["events"] == 0 # events + assert results[RUN_RESULTS_KEY][context_name]["biz_events"] == rows_cnt # bizevents + assert results[RUN_RESULTS_KEY][context_name]["davis_events"] == 0 # davis_events @pytest.mark.xdist_group(name="test_telemetry") def test_connector_bizevents(self): @@ -111,6 +122,7 @@ def test_connector_bizevents(self): session, {"auto_mode": False, "logs": False, "events": False, "bizevents": True}, config=_utils.get_config(), + exec_id=str(uuid.uuid4().hex), ) data = [ { @@ -120,6 +132,7 @@ def test_connector_bizevents(self): "dsoa.task.exec.status": "FINISHED", } ] + context_name = "telemetry_sender" mock_client = MockTelemetryClient("test_connector_bizevents") with mock_client.mock_telemetry_sending(): results = sender.send_data(data) @@ -127,7 +140,10 @@ def test_connector_bizevents(self): sender._spans.shutdown_tracer() mock_client.store_or_test_results() - assert results["biz_events"] == 1 + assert RUN_RESULTS_KEY in results + assert context_name in results[RUN_RESULTS_KEY] + assert RUN_ID_KEY in results + assert results[RUN_RESULTS_KEY][context_name]["biz_events"] == 1 @pytest.mark.xdist_group(name="test_telemetry") def test_automode(self): @@ -145,7 +161,14 @@ def test_automode(self): {"context": "test_automode/000"}, config=_utils.get_config(), test_source="test_automode/000", - ) == {"entries": 2, "log_lines": 2, "metrics": 7, "events": 3, "biz_events": 0, "davis_events": 0} + )[RUN_RESULTS_KEY]["test_automode/000"] == { + "entries": 2, + "log_lines": 2, + "metrics": 7, + "events": 3, + "biz_events": 0, + "davis_events": 0, + } # sending data from a given (standard structure) view, excluding metrics assert telemetry_test_sender( session, @@ -153,7 +176,14 @@ def test_automode(self): {"context": "test_automode/001", "metrics": False}, config=_utils.get_config(), test_source="test_automode/001", - ) == {"entries": 2, "log_lines": 2, "metrics": 0, "events": 3, "biz_events": 0, "davis_events": 0} + )[RUN_RESULTS_KEY]["test_automode/001"] == { + "entries": 2, + "log_lines": 2, + "metrics": 0, + "events": 3, + "biz_events": 0, + "davis_events": 0, + } # sending data from a given (standard structure) view, excluding events assert telemetry_test_sender( session, @@ -161,7 +191,14 @@ def test_automode(self): {"context": "test_automode/002", "events": False}, config=_utils.get_config(), test_source="test_automode/002", - ) == {"entries": 2, "log_lines": 2, "metrics": 7, "events": 0, "biz_events": 0, "davis_events": 0} + )[RUN_RESULTS_KEY]["test_automode/002"] == { + "entries": 2, + "log_lines": 2, + "metrics": 7, + "events": 0, + "biz_events": 0, + "davis_events": 0, + } # sending data from a given (standard structure) view, excluding logs assert telemetry_test_sender( session, @@ -169,7 +206,14 @@ def test_automode(self): {"context": "test_automode/003", "logs": False}, config=_utils.get_config(), test_source="test_automode/003", - ) == {"entries": 2, "log_lines": 0, "metrics": 7, "events": 3, "biz_events": 0, "davis_events": 0} + )[RUN_RESULTS_KEY]["test_automode/003"] == { + "entries": 2, + "log_lines": 0, + "metrics": 7, + "events": 3, + "biz_events": 0, + "davis_events": 0, + } # sending all data from a given (standard structure) object assert telemetry_test_sender( @@ -178,7 +222,14 @@ def test_automode(self): {"context": "test_automode/004"}, config=_utils.get_config(), test_source="test_automode/004", - ) == {"entries": 1, "log_lines": 1, "metrics": 4, "events": 2, "biz_events": 0, "davis_events": 0} + )[RUN_RESULTS_KEY]["test_automode/004"] == { + "entries": 1, + "log_lines": 1, + "metrics": 4, + "events": 2, + "biz_events": 0, + "davis_events": 0, + } # sending all data from a given (standard structure) view assert telemetry_test_sender( session, @@ -186,7 +237,14 @@ def test_automode(self): {"context": "test_automode/005"}, config=_utils.get_config(), test_source="test_automode/005", - ) == {"entries": 2, "log_lines": 2, "metrics": 7, "events": 3, "biz_events": 0, "davis_events": 0} + )[RUN_RESULTS_KEY]["test_automode/005"] == { + "entries": 2, + "log_lines": 2, + "metrics": 7, + "events": 3, + "biz_events": 0, + "davis_events": 0, + } # sending data from a given (standard structure) view, excluding metrics assert telemetry_test_sender( session, @@ -194,7 +252,14 @@ def test_automode(self): {"context": "test_automode/006", "metrics": False}, config=_utils.get_config(), test_source="test_automode/006", - ) == {"entries": 2, "log_lines": 2, "metrics": 0, "events": 3, "biz_events": 0, "davis_events": 0} + )[RUN_RESULTS_KEY]["test_automode/006"] == { + "entries": 2, + "log_lines": 2, + "metrics": 0, + "events": 3, + "biz_events": 0, + "davis_events": 0, + } # sending data from a given (standard structure) view, excluding events assert telemetry_test_sender( session, @@ -202,7 +267,14 @@ def test_automode(self): {"context": "test_automode/007", "events": False}, config=_utils.get_config(), test_source="test_automode/007", - ) == {"entries": 2, "log_lines": 2, "metrics": 7, "events": 0, "biz_events": 0, "davis_events": 0} + )[RUN_RESULTS_KEY]["test_automode/007"] == { + "entries": 2, + "log_lines": 2, + "metrics": 7, + "events": 0, + "biz_events": 0, + "davis_events": 0, + } # sending data from a given (standard structure) view, excluding logs assert telemetry_test_sender( session, @@ -210,7 +282,14 @@ def test_automode(self): {"context": "test_automode/008", "logs": False}, config=_utils.get_config(), test_source="test_automode/008", - ) == {"entries": 2, "log_lines": 0, "metrics": 7, "events": 3, "biz_events": 0, "davis_events": 0} + )[RUN_RESULTS_KEY]["test_automode/008"] == { + "entries": 2, + "log_lines": 0, + "metrics": 7, + "events": 3, + "biz_events": 0, + "davis_events": 0, + } # sending all data from a given (custom structure) view as logs assert telemetry_test_sender( @@ -219,7 +298,14 @@ def test_automode(self): {"context": "test_automode/009", "auto_mode": False}, config=_utils.get_config(), test_source="test_automode/009", - ) == {"entries": 3, "log_lines": 3, "metrics": 0, "events": 0, "biz_events": 0, "davis_events": 0} + )[RUN_RESULTS_KEY]["test_automode/009"] == { + "entries": 3, + "log_lines": 3, + "metrics": 0, + "events": 0, + "biz_events": 0, + "davis_events": 0, + } # sending all data from a given (custom structure) view as events assert telemetry_test_sender( session, @@ -227,7 +313,14 @@ def test_automode(self): {"context": "test_automode/010", "auto_mode": False, "logs": False, "events": True, "davis_events": True}, config=_utils.get_config(), test_source="test_automode/010", - ) == {"entries": 3, "log_lines": 0, "metrics": 0, "events": 3, "biz_events": 0, "davis_events": 3} + )[RUN_RESULTS_KEY]["test_automode/010"] == { + "entries": 3, + "log_lines": 0, + "metrics": 0, + "events": 3, + "biz_events": 0, + "davis_events": 3, + } # sending all data from a given (custom structure) view as bizevents assert telemetry_test_sender( session, @@ -235,7 +328,14 @@ def test_automode(self): {"context": "test_automode/011", "auto_mode": False, "logs": False, "bizevents": True}, config=_utils.get_config(), test_source="test_automode/011", - ) == {"entries": 3, "log_lines": 0, "metrics": 0, "events": 0, "biz_events": 3, "davis_events": 0} + )[RUN_RESULTS_KEY]["test_automode/011"] == { + "entries": 3, + "log_lines": 0, + "metrics": 0, + "events": 0, + "biz_events": 3, + "davis_events": 0, + } # sending all data from a given (custom structure) view as logs, events, and bizevents assert telemetry_test_sender( session, @@ -243,7 +343,14 @@ def test_automode(self): {"context": "test_automode/012", "auto_mode": False, "logs": True, "events": True, "bizevents": True}, config=_utils.get_config(), test_source="test_automode/012", - ) == {"entries": 3, "log_lines": 3, "metrics": 0, "events": 3, "biz_events": 3, "davis_events": 0} + )[RUN_RESULTS_KEY]["test_automode/012"] == { + "entries": 3, + "log_lines": 3, + "metrics": 0, + "events": 3, + "biz_events": 3, + "davis_events": 0, + } # sending single data point from a given (custom structure) view as logs, events, and bizevents assert telemetry_test_sender( session, @@ -251,7 +358,14 @@ def test_automode(self): {"context": "test_automode/013", "auto_mode": False, "logs": True, "events": True, "bizevents": True}, config=_utils.get_config(), test_source="test_automode/013", - ) == {"entries": 1, "log_lines": 1, "metrics": 0, "events": 1, "biz_events": 1, "davis_events": 0} + )[RUN_RESULTS_KEY]["test_automode/013"] == { + "entries": 1, + "log_lines": 1, + "metrics": 0, + "events": 1, + "biz_events": 1, + "davis_events": 0, + } # sending single data point from a given (custom structure) with datetime objects view as logs, events, and bizevents assert telemetry_test_sender( session, @@ -259,4 +373,11 @@ def test_automode(self): {"context": "test_automode/014", "auto_mode": False, "logs": True, "events": True, "bizevents": True}, config=_utils.get_config(), test_source="test_automode/014", - ) == {"entries": 1, "log_lines": 1, "metrics": 0, "events": 1, "biz_events": 1, "davis_events": 0} + )[RUN_RESULTS_KEY]["test_automode/014"] == { + "entries": 1, + "log_lines": 1, + "metrics": 0, + "events": 1, + "biz_events": 1, + "davis_events": 0, + } diff --git a/test/core/test_documentation.py b/test/core/test_documentation.py index 648a262c..d28b018d 100644 --- a/test/core/test_documentation.py +++ b/test/core/test_documentation.py @@ -104,9 +104,11 @@ def test_matching_documentation(self): assert not missing_sql, f"We have documentation for fields not reported in telemetry:\n {missing_sql_listed}" found_core_dimension = [ - entry for entry in semantics if entry["name"] == context.CONTEXT_NAME and entry["plugin"] == "" and entry["type"] == "dimension" + entry + for entry in semantics + if entry["name"] == context.RUN_CONTEXT_KEY and entry["plugin"] == "" and entry["type"] == "dimension" ] - assert found_core_dimension, f"Did not find core dimension <{context.CONTEXT_NAME}>" + assert found_core_dimension, f"Did not find core dimension <{context.RUN_CONTEXT_KEY}>" core_dimensions = set(Configuration.RESOURCE_ATTRIBUTES.keys()) found_core_dimensions = set( diff --git a/test/otel/test_events.py b/test/otel/test_events.py index 63c761c7..3e9c05be 100644 --- a/test/otel/test_events.py +++ b/test/otel/test_events.py @@ -21,6 +21,7 @@ # SOFTWARE. # # +import uuid from unittest.mock import patch from dtagent.otel.events import EventType @@ -51,7 +52,7 @@ def test_eventtype_enum(self): assert str(t) == "CUSTOM_ALERT", "event type {t} should render in capital letters" def test_send_events_directly(self): - + # FIXME def _test_send_events_directly(test_mode="davis"): import time @@ -127,7 +128,9 @@ def _test_send_events_directly(test_mode="davis"): additional_payload={ "test.event.dtagent.info": "15 min in the future", }, - context=get_context_name_and_run_id("data_volume"), + context=get_context_name_and_run_id( + plugin_name="test_send_events_directly", context_name="data_volume", run_id=str(uuid.uuid4().hex) + ), end_time=fifteen_minutes_from_now_ms, ) assert events_sent + events.flush_events() >= 0 @@ -228,7 +231,9 @@ def test_send_results_as_bizevents(self): events_sent = bizevents.report_via_api( query_data=_utils._get_unpickled_entries(PICKLE_NAME, limit=2), event_type=str(EventType.CUSTOM_INFO), - context=get_context_name_and_run_id("data_volume"), + context=get_context_name_and_run_id( + plugin_name="test_send_results_as_bizevents", context_name="data_volume", run_id=str(uuid.uuid4().hex) + ), ) events_sent += bizevents.flush_events() @@ -242,7 +247,9 @@ def test_dtagent_bizevents(self): bizevents = self._dtagent._get_biz_events() cnt = bizevents.report_via_api( - context=get_context_name_and_run_id("self-monitoring"), + context=get_context_name_and_run_id( + plugin_name="test_send_events_directly", context_name="self_monitoring", run_id=str(uuid.uuid4().hex) + ), event_type="dsoa.task", query_data=[ { diff --git a/test/otel/test_otel_manager.py b/test/otel/test_otel_manager.py index 2c064e2e..d26e3f6e 100644 --- a/test/otel/test_otel_manager.py +++ b/test/otel/test_otel_manager.py @@ -21,7 +21,7 @@ # SOFTWARE. # # - +import uuid import pytest from dtagent.otel.otel_manager import OtelManager from test._utils import LocalTelemetrySender, get_config, read_clean_json_from_file @@ -43,7 +43,10 @@ def test_otel_manager_throw_exception(self): session = _get_session() sender = LocalTelemetrySender( - session, {"auto_mode": False, "logs": False, "events": True, "bizevents": True, "metrics": True}, config=get_config() + session, + {"auto_mode": False, "logs": False, "events": True, "bizevents": True, "metrics": True}, + config=get_config(), + exec_id=str(uuid.uuid4().hex), ) OtelManager.set_max_fail_count(max_fails_allowed) diff --git a/test/plugins/test_login_history.py b/test/plugins/test_login_history.py index cb6e570d..92463eae 100644 --- a/test/plugins/test_login_history.py +++ b/test/plugins/test_login_history.py @@ -63,12 +63,12 @@ def __local_get_plugin_class(source: str): for disabled_telemetry in disabled_combinations: utils.execute_telemetry_test( TestDynatraceSnowAgent, - test_name="login_history", + test_name="test_login_history", disabled_telemetry=disabled_telemetry, affecting_types_for_entries=["logs", "events"], base_count={ - "login_history": {"entries": 2, "logs": 2, "metrics": 0, "events": 0}, - "sessions": {"entries": 0, "logs": 0, "metrics": 0, "events": 0}, + "login_history": {"entries": 2, "log_lines": 2, "metrics": 0, "events": 0}, + "sessions": {"entries": 0, "log_lines": 0, "metrics": 0, "events": 0}, }, ) diff --git a/test/test_results/login_history/biz_events.json b/test/test_results/login_history/biz_events.json deleted file mode 100644 index 500f90ac..00000000 --- a/test/test_results/login_history/biz_events.json +++ /dev/null @@ -1,38 +0,0 @@ -[ - { - "specversion": "1.0", - "source": "test.dsoa2025.snowflakecomputing.com", - "type": "dsoa.task", - "data": { - "event.provider": "test.dsoa2025.snowflakecomputing.com", - "dsoa.task.name": "login_history", - "dsoa.task.exec.status": "STARTED", - "app.bundle": "self-monitoring", - "app.id": "dynatrace.snowagent", - "db.system": "snowflake", - "service.name": "test.dsoa2025", - "deployment.environment": "TEST", - "host.name": "test.dsoa2025.snowflakecomputing.com", - "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" - } - }, - { - "specversion": "1.0", - "source": "test.dsoa2025.snowflakecomputing.com", - "type": "dsoa.task", - "data": { - "event.provider": "test.dsoa2025.snowflakecomputing.com", - "dsoa.task.name": "login_history", - "dsoa.task.exec.status": "FINISHED", - "app.bundle": "self-monitoring", - "app.id": "dynatrace.snowagent", - "db.system": "snowflake", - "service.name": "test.dsoa2025", - "deployment.environment": "TEST", - "host.name": "test.dsoa2025.snowflakecomputing.com", - "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" - } - } -] \ No newline at end of file diff --git a/test/test_results/test_active_queries/biz_events.json b/test/test_results/test_active_queries/biz_events.json index 627bd959..39acd3f3 100644 --- a/test/test_results/test_active_queries/biz_events.json +++ b/test/test_results/test_active_queries/biz_events.json @@ -7,14 +7,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_active_queries", "dsoa.task.exec.status": "STARTED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "test_active_queries" } }, { @@ -25,14 +26,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_active_queries", "dsoa.task.exec.status": "FINISHED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "test_active_queries" } } -] +] \ No newline at end of file diff --git a/test/test_results/test_active_queries/logs.json b/test/test_results/test_active_queries/logs.json index e367d024..2821de32 100644 --- a/test/test_results/test_active_queries/logs.json +++ b/test/test_results/test_active_queries/logs.json @@ -22,7 +22,8 @@ "snowflake.query.execution_status": "SUCCESS", "snowflake.role.name": "DTAGENT_SKRUK_ADMIN", "snowflake.warehouse.name": "DTAGENT_SKRUK_WH", - "dsoa.run.context": "active_queries" + "dsoa.run.context": "active_queries", + "dsoa.run.plugin": "test_active_queries" }, { "content": "SQL query SUCCESS at DTAGENT_SKRUK_DB", @@ -47,6 +48,7 @@ "snowflake.query.execution_status": "SUCCESS", "snowflake.role.name": "DTAGENT_SKRUK_ADMIN", "snowflake.warehouse.name": "DTAGENT_SKRUK_WH", - "dsoa.run.context": "active_queries" + "dsoa.run.context": "active_queries", + "dsoa.run.plugin": "test_active_queries" } -] \ No newline at end of file +] diff --git a/test/test_results/test_automode/000/biz_events.json b/test/test_results/test_automode/000/biz_events.json index d3074e87..36dcabf9 100644 --- a/test/test_results/test_automode/000/biz_events.json +++ b/test/test_results/test_automode/000/biz_events.json @@ -7,14 +7,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_automode/000", "dsoa.task.exec.status": "STARTED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "telemetry_sender" } }, { @@ -25,14 +26,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_automode/000", "dsoa.task.exec.status": "FINISHED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "telemetry_sender" } } -] +] \ No newline at end of file diff --git a/test/test_results/test_automode/000/events.json b/test/test_results/test_automode/000/events.json index 88a56d5c..902d8d8b 100644 --- a/test/test_results/test_automode/000/events.json +++ b/test/test_results/test_automode/000/events.json @@ -15,7 +15,8 @@ "telemetry.exporter.name": "dynatrace.snowagent", "dsoa.run.context": "test_automode/000", "eventType": "CUSTOM_INFO", - "title": "Table event snowflake.table.update." + "title": "Table event snowflake.table.update.", + "dsoa.run.plugin": "telemetry_sender" }, { "snowflake.event.trigger": "snowflake.table.ddl", @@ -35,7 +36,8 @@ "telemetry.exporter.name": "dynatrace.snowagent", "dsoa.run.context": "test_automode/000", "eventType": "CUSTOM_INFO", - "title": "Table event snowflake.table.ddl." + "title": "Table event snowflake.table.ddl.", + "dsoa.run.plugin": "telemetry_sender" }, { "snowflake.event.trigger": "snowflake.table.update", @@ -55,6 +57,7 @@ "telemetry.exporter.name": "dynatrace.snowagent", "dsoa.run.context": "test_automode/000", "eventType": "CUSTOM_INFO", - "title": "Table event snowflake.table.update." + "title": "Table event snowflake.table.update.", + "dsoa.run.plugin": "telemetry_sender" } ] diff --git a/test/test_results/test_automode/000/logs.json b/test/test_results/test_automode/000/logs.json index dd69ab0d..4d47d892 100644 --- a/test/test_results/test_automode/000/logs.json +++ b/test/test_results/test_automode/000/logs.json @@ -8,6 +8,7 @@ "snowflake.table.type": "BASE TABLE", "db.collection.name": "DEV_DB.PUBLIC.SALESMANAGERREGIONS", "db.namespace": "DEV_DB", + "dsoa.run.plugin": "telemetry_sender", "dsoa.run.context": "test_automode/000" }, { @@ -19,14 +20,20 @@ "snowflake.table.type": "BASE TABLE", "db.collection.name": "DTAGENT_DB.STATUS.PROCESSED_QUERIES_CACHE", "db.namespace": "DTAGENT_DB", + "dsoa.run.plugin": "telemetry_sender", "dsoa.run.context": "test_automode/000" }, { "content": "New entry to STATUS.LOG_PROCESSED_MEASUREMENTS from test_automode/000", - "entries": 2, - "log_lines": 2, - "metrics": 7, - "events": 3, + "test_automode/000": { + "biz_events": 0, + "davis_events": 0, + "entries": 2, + "events": 3, + "log_lines": 2, + "metrics": 7 + }, + "dsoa.run.plugin": "telemetry_sender", "dsoa.run.context": "self_monitoring" } -] \ No newline at end of file +] diff --git a/test/test_results/test_automode/001/biz_events.json b/test/test_results/test_automode/001/biz_events.json index 55956e1b..df4cb98e 100644 --- a/test/test_results/test_automode/001/biz_events.json +++ b/test/test_results/test_automode/001/biz_events.json @@ -7,14 +7,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_automode/001", "dsoa.task.exec.status": "STARTED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "telemetry_sender" } }, { @@ -25,14 +26,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_automode/001", "dsoa.task.exec.status": "FINISHED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "telemetry_sender" } } -] +] \ No newline at end of file diff --git a/test/test_results/test_automode/001/events.json b/test/test_results/test_automode/001/events.json index 856c2937..ea429cff 100644 --- a/test/test_results/test_automode/001/events.json +++ b/test/test_results/test_automode/001/events.json @@ -15,7 +15,8 @@ "telemetry.exporter.name": "dynatrace.snowagent", "dsoa.run.context": "test_automode/001", "eventType": "CUSTOM_INFO", - "title": "Table event snowflake.table.update." + "title": "Table event snowflake.table.update.", + "dsoa.run.plugin": "telemetry_sender" }, { "snowflake.event.trigger": "snowflake.table.ddl", @@ -35,7 +36,8 @@ "telemetry.exporter.name": "dynatrace.snowagent", "dsoa.run.context": "test_automode/001", "eventType": "CUSTOM_INFO", - "title": "Table event snowflake.table.ddl." + "title": "Table event snowflake.table.ddl.", + "dsoa.run.plugin": "telemetry_sender" }, { "snowflake.event.trigger": "snowflake.table.update", @@ -55,6 +57,7 @@ "telemetry.exporter.name": "dynatrace.snowagent", "dsoa.run.context": "test_automode/001", "eventType": "CUSTOM_INFO", - "title": "Table event snowflake.table.update." + "title": "Table event snowflake.table.update.", + "dsoa.run.plugin": "telemetry_sender" } ] diff --git a/test/test_results/test_automode/001/logs.json b/test/test_results/test_automode/001/logs.json index fc3e8d97..ee603a4d 100644 --- a/test/test_results/test_automode/001/logs.json +++ b/test/test_results/test_automode/001/logs.json @@ -8,7 +8,8 @@ "snowflake.table.type": "BASE TABLE", "db.collection.name": "DEV_DB.PUBLIC.SALESMANAGERREGIONS", "db.namespace": "DEV_DB", - "dsoa.run.context": "test_automode/001" + "dsoa.run.context": "test_automode/001", + "dsoa.run.plugin": "telemetry_sender" }, { "content": "test_automode/001", @@ -19,13 +20,20 @@ "snowflake.table.type": "BASE TABLE", "db.collection.name": "DTAGENT_DB.STATUS.PROCESSED_QUERIES_CACHE", "db.namespace": "DTAGENT_DB", - "dsoa.run.context": "test_automode/001" + "dsoa.run.context": "test_automode/001", + "dsoa.run.plugin": "telemetry_sender" }, { "content": "New entry to STATUS.LOG_PROCESSED_MEASUREMENTS from test_automode/001", - "entries": 2, - "log_lines": 2, - "events": 3, - "dsoa.run.context": "self_monitoring" + "test_automode/001": { + "biz_events": 0, + "davis_events": 0, + "entries": 2, + "events": 3, + "log_lines": 2, + "metrics": 0 + }, + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "telemetry_sender" } -] \ No newline at end of file +] diff --git a/test/test_results/test_automode/002/biz_events.json b/test/test_results/test_automode/002/biz_events.json index 969606de..106c0478 100644 --- a/test/test_results/test_automode/002/biz_events.json +++ b/test/test_results/test_automode/002/biz_events.json @@ -7,14 +7,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_automode/002", "dsoa.task.exec.status": "STARTED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "telemetry_sender" } }, { @@ -25,14 +26,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_automode/002", "dsoa.task.exec.status": "FINISHED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "telemetry_sender" } } -] +] \ No newline at end of file diff --git a/test/test_results/test_automode/002/logs.json b/test/test_results/test_automode/002/logs.json index d81f6f82..d9753c8f 100644 --- a/test/test_results/test_automode/002/logs.json +++ b/test/test_results/test_automode/002/logs.json @@ -8,7 +8,8 @@ "snowflake.table.type": "BASE TABLE", "db.collection.name": "DEV_DB.PUBLIC.SALESMANAGERREGIONS", "db.namespace": "DEV_DB", - "dsoa.run.context": "test_automode/002" + "dsoa.run.context": "test_automode/002", + "dsoa.run.plugin": "telemetry_sender" }, { "content": "test_automode/002", @@ -19,13 +20,20 @@ "snowflake.table.type": "BASE TABLE", "db.collection.name": "DTAGENT_DB.STATUS.PROCESSED_QUERIES_CACHE", "db.namespace": "DTAGENT_DB", - "dsoa.run.context": "test_automode/002" + "dsoa.run.context": "test_automode/002", + "dsoa.run.plugin": "telemetry_sender" }, { "content": "New entry to STATUS.LOG_PROCESSED_MEASUREMENTS from test_automode/002", - "entries": 2, - "log_lines": 2, - "metrics": 7, - "dsoa.run.context": "self_monitoring" + "test_automode/002": { + "biz_events": 0, + "davis_events": 0, + "entries": 2, + "events": 0, + "log_lines": 2, + "metrics": 7 + }, + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "telemetry_sender" } -] \ No newline at end of file +] diff --git a/test/test_results/test_automode/003/biz_events.json b/test/test_results/test_automode/003/biz_events.json index 43b8a2be..cf08d92a 100644 --- a/test/test_results/test_automode/003/biz_events.json +++ b/test/test_results/test_automode/003/biz_events.json @@ -7,14 +7,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_automode/003", "dsoa.task.exec.status": "STARTED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "telemetry_sender" } }, { @@ -25,14 +26,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_automode/003", "dsoa.task.exec.status": "FINISHED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "telemetry_sender" } } -] +] \ No newline at end of file diff --git a/test/test_results/test_automode/003/events.json b/test/test_results/test_automode/003/events.json index de8f66eb..da4f39da 100644 --- a/test/test_results/test_automode/003/events.json +++ b/test/test_results/test_automode/003/events.json @@ -15,7 +15,8 @@ "telemetry.exporter.name": "dynatrace.snowagent", "dsoa.run.context": "test_automode/003", "eventType": "CUSTOM_INFO", - "title": "Table event snowflake.table.update." + "title": "Table event snowflake.table.update.", + "dsoa.run.plugin": "telemetry_sender" }, { "snowflake.event.trigger": "snowflake.table.ddl", @@ -35,7 +36,8 @@ "telemetry.exporter.name": "dynatrace.snowagent", "dsoa.run.context": "test_automode/003", "eventType": "CUSTOM_INFO", - "title": "Table event snowflake.table.ddl." + "title": "Table event snowflake.table.ddl.", + "dsoa.run.plugin": "telemetry_sender" }, { "snowflake.event.trigger": "snowflake.table.update", @@ -55,6 +57,7 @@ "telemetry.exporter.name": "dynatrace.snowagent", "dsoa.run.context": "test_automode/003", "eventType": "CUSTOM_INFO", - "title": "Table event snowflake.table.update." + "title": "Table event snowflake.table.update.", + "dsoa.run.plugin": "telemetry_sender" } ] diff --git a/test/test_results/test_automode/003/logs.json b/test/test_results/test_automode/003/logs.json index 71156b73..41e639d8 100644 --- a/test/test_results/test_automode/003/logs.json +++ b/test/test_results/test_automode/003/logs.json @@ -1,9 +1,15 @@ [ { "content": "New entry to STATUS.LOG_PROCESSED_MEASUREMENTS from test_automode/003", - "entries": 2, - "metrics": 7, - "events": 3, - "dsoa.run.context": "self_monitoring" + "test_automode/003": { + "biz_events": 0, + "davis_events": 0, + "entries": 2, + "events": 3, + "log_lines": 0, + "metrics": 7 + }, + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "telemetry_sender" } -] \ No newline at end of file +] diff --git a/test/test_results/test_automode/004/biz_events.json b/test/test_results/test_automode/004/biz_events.json index 7b920f12..4e86e3f9 100644 --- a/test/test_results/test_automode/004/biz_events.json +++ b/test/test_results/test_automode/004/biz_events.json @@ -7,14 +7,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_automode/004", "dsoa.task.exec.status": "STARTED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "telemetry_sender" } }, { @@ -25,14 +26,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_automode/004", "dsoa.task.exec.status": "FINISHED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "telemetry_sender" } } -] +] \ No newline at end of file diff --git a/test/test_results/test_automode/004/events.json b/test/test_results/test_automode/004/events.json index 0df4d588..86e72b0a 100644 --- a/test/test_results/test_automode/004/events.json +++ b/test/test_results/test_automode/004/events.json @@ -17,7 +17,8 @@ "telemetry.exporter.name": "dynatrace.snowagent", "dsoa.run.context": "test_automode/004", "eventType": "CUSTOM_INFO", - "title": "Table event data_update." + "title": "Table event data_update.", + "dsoa.run.plugin": "telemetry_sender" }, { "snowflake.event.trigger": "ddl", @@ -37,6 +38,7 @@ "telemetry.exporter.name": "dynatrace.snowagent", "dsoa.run.context": "test_automode/004", "eventType": "CUSTOM_INFO", - "title": "Table event ddl." + "title": "Table event ddl.", + "dsoa.run.plugin": "telemetry_sender" } ] diff --git a/test/test_results/test_automode/004/logs.json b/test/test_results/test_automode/004/logs.json index ddfc4fb0..f67a29df 100644 --- a/test/test_results/test_automode/004/logs.json +++ b/test/test_results/test_automode/004/logs.json @@ -8,14 +8,20 @@ "snowflake.table_type": "BASE TABLE", "db.collection.name": "DTAGENT_DB.STATUS.PROCESSED_QUERIES_CACHE", "db.namespace": "DTAGENT_DB", - "dsoa.run.context": "test_automode/004" + "dsoa.run.context": "test_automode/004", + "dsoa.run.plugin": "telemetry_sender" }, { "content": "New entry to STATUS.LOG_PROCESSED_MEASUREMENTS from test_automode/004", - "entries": 1, - "log_lines": 1, - "metrics": 4, - "events": 2, - "dsoa.run.context": "self_monitoring" + "test_automode/004": { + "biz_events": 0, + "davis_events": 0, + "entries": 1, + "events": 2, + "log_lines": 1, + "metrics": 4 + }, + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "telemetry_sender" } -] \ No newline at end of file +] diff --git a/test/test_results/test_automode/005/biz_events.json b/test/test_results/test_automode/005/biz_events.json index 16eabd31..36747a88 100644 --- a/test/test_results/test_automode/005/biz_events.json +++ b/test/test_results/test_automode/005/biz_events.json @@ -7,14 +7,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_automode/005", "dsoa.task.exec.status": "STARTED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "telemetry_sender" } }, { @@ -25,14 +26,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_automode/005", "dsoa.task.exec.status": "FINISHED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "telemetry_sender" } } -] +] \ No newline at end of file diff --git a/test/test_results/test_automode/005/events.json b/test/test_results/test_automode/005/events.json index 971ee1db..d4730a65 100644 --- a/test/test_results/test_automode/005/events.json +++ b/test/test_results/test_automode/005/events.json @@ -17,7 +17,8 @@ "telemetry.exporter.name": "dynatrace.snowagent", "dsoa.run.context": "test_automode/005", "eventType": "CUSTOM_INFO", - "title": "Table event data_update." + "title": "Table event data_update.", + "dsoa.run.plugin": "telemetry_sender" }, { "snowflake.event.trigger": "ddl", @@ -37,7 +38,8 @@ "telemetry.exporter.name": "dynatrace.snowagent", "dsoa.run.context": "test_automode/005", "eventType": "CUSTOM_INFO", - "title": "Table event ddl." + "title": "Table event ddl.", + "dsoa.run.plugin": "telemetry_sender" }, { "snowflake.event.trigger": "data_update", @@ -55,6 +57,7 @@ "telemetry.exporter.name": "dynatrace.snowagent", "dsoa.run.context": "test_automode/005", "eventType": "CUSTOM_INFO", - "title": "Table event data_update." + "title": "Table event data_update.", + "dsoa.run.plugin": "telemetry_sender" } ] diff --git a/test/test_results/test_automode/005/logs.json b/test/test_results/test_automode/005/logs.json index 656ba314..a140bcc0 100644 --- a/test/test_results/test_automode/005/logs.json +++ b/test/test_results/test_automode/005/logs.json @@ -8,7 +8,8 @@ "snowflake.table_type": "BASE TABLE", "db.collection.name": "DTAGENT_DB.STATUS.PROCESSED_QUERIES_CACHE", "db.namespace": "DTAGENT_DB", - "dsoa.run.context": "test_automode/005" + "dsoa.run.context": "test_automode/005", + "dsoa.run.plugin": "telemetry_sender" }, { "content": "test_automode/005", @@ -19,14 +20,20 @@ "snowflake.table_type": "BASE TABLE", "db.collection.name": "DEV_DB.PUBLIC.SALES", "db.namespace": "DEV_DB", - "dsoa.run.context": "test_automode/005" + "dsoa.run.context": "test_automode/005", + "dsoa.run.plugin": "telemetry_sender" }, { "content": "New entry to STATUS.LOG_PROCESSED_MEASUREMENTS from test_automode/005", - "entries": 2, - "log_lines": 2, - "metrics": 7, - "events": 3, - "dsoa.run.context": "self_monitoring" + "test_automode/005": { + "biz_events": 0, + "davis_events": 0, + "entries": 2, + "events": 3, + "log_lines": 2, + "metrics": 7 + }, + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "telemetry_sender" } -] \ No newline at end of file +] diff --git a/test/test_results/test_automode/006/biz_events.json b/test/test_results/test_automode/006/biz_events.json index e5b05929..00e7c719 100644 --- a/test/test_results/test_automode/006/biz_events.json +++ b/test/test_results/test_automode/006/biz_events.json @@ -7,14 +7,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_automode/006", "dsoa.task.exec.status": "STARTED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "telemetry_sender" } }, { @@ -25,14 +26,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_automode/006", "dsoa.task.exec.status": "FINISHED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "telemetry_sender" } } -] +] \ No newline at end of file diff --git a/test/test_results/test_automode/006/events.json b/test/test_results/test_automode/006/events.json index a4c15e49..7db758d2 100644 --- a/test/test_results/test_automode/006/events.json +++ b/test/test_results/test_automode/006/events.json @@ -17,7 +17,8 @@ "telemetry.exporter.name": "dynatrace.snowagent", "dsoa.run.context": "test_automode/006", "eventType": "CUSTOM_INFO", - "title": "Table event data_update." + "title": "Table event data_update.", + "dsoa.run.plugin": "telemetry_sender" }, { "snowflake.event.trigger": "ddl", @@ -37,7 +38,8 @@ "telemetry.exporter.name": "dynatrace.snowagent", "dsoa.run.context": "test_automode/006", "eventType": "CUSTOM_INFO", - "title": "Table event ddl." + "title": "Table event ddl.", + "dsoa.run.plugin": "telemetry_sender" }, { "snowflake.event.trigger": "data_update", @@ -55,6 +57,7 @@ "telemetry.exporter.name": "dynatrace.snowagent", "dsoa.run.context": "test_automode/006", "eventType": "CUSTOM_INFO", - "title": "Table event data_update." + "title": "Table event data_update.", + "dsoa.run.plugin": "telemetry_sender" } ] diff --git a/test/test_results/test_automode/006/logs.json b/test/test_results/test_automode/006/logs.json index 5c5c0ea7..788d8a2a 100644 --- a/test/test_results/test_automode/006/logs.json +++ b/test/test_results/test_automode/006/logs.json @@ -8,7 +8,8 @@ "snowflake.table_type": "BASE TABLE", "db.collection.name": "DTAGENT_DB.STATUS.PROCESSED_QUERIES_CACHE", "db.namespace": "DTAGENT_DB", - "dsoa.run.context": "test_automode/006" + "dsoa.run.context": "test_automode/006", + "dsoa.run.plugin": "telemetry_sender" }, { "content": "test_automode/006", @@ -19,13 +20,20 @@ "snowflake.table_type": "BASE TABLE", "db.collection.name": "DEV_DB.PUBLIC.SALES", "db.namespace": "DEV_DB", - "dsoa.run.context": "test_automode/006" + "dsoa.run.context": "test_automode/006", + "dsoa.run.plugin": "telemetry_sender" }, { "content": "New entry to STATUS.LOG_PROCESSED_MEASUREMENTS from test_automode/006", - "entries": 2, - "log_lines": 2, - "events": 3, - "dsoa.run.context": "self_monitoring" + "test_automode/006": { + "biz_events": 0, + "davis_events": 0, + "entries": 2, + "events": 3, + "log_lines": 2, + "metrics": 0 + }, + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "telemetry_sender" } -] \ No newline at end of file +] diff --git a/test/test_results/test_automode/007/biz_events.json b/test/test_results/test_automode/007/biz_events.json index 1d898afa..e08050b6 100644 --- a/test/test_results/test_automode/007/biz_events.json +++ b/test/test_results/test_automode/007/biz_events.json @@ -7,14 +7,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_automode/007", "dsoa.task.exec.status": "STARTED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "telemetry_sender" } }, { @@ -25,14 +26,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_automode/007", "dsoa.task.exec.status": "FINISHED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "telemetry_sender" } } -] +] \ No newline at end of file diff --git a/test/test_results/test_automode/007/logs.json b/test/test_results/test_automode/007/logs.json index bf9215f8..0d7352f4 100644 --- a/test/test_results/test_automode/007/logs.json +++ b/test/test_results/test_automode/007/logs.json @@ -8,7 +8,8 @@ "snowflake.table_type": "BASE TABLE", "db.collection.name": "DTAGENT_DB.STATUS.PROCESSED_QUERIES_CACHE", "db.namespace": "DTAGENT_DB", - "dsoa.run.context": "test_automode/007" + "dsoa.run.context": "test_automode/007", + "dsoa.run.plugin": "telemetry_sender" }, { "content": "test_automode/007", @@ -19,13 +20,20 @@ "snowflake.table_type": "BASE TABLE", "db.collection.name": "DEV_DB.PUBLIC.SALES", "db.namespace": "DEV_DB", - "dsoa.run.context": "test_automode/007" + "dsoa.run.context": "test_automode/007", + "dsoa.run.plugin": "telemetry_sender" }, { "content": "New entry to STATUS.LOG_PROCESSED_MEASUREMENTS from test_automode/007", - "entries": 2, - "log_lines": 2, - "metrics": 7, - "dsoa.run.context": "self_monitoring" + "test_automode/007": { + "biz_events": 0, + "davis_events": 0, + "entries": 2, + "events": 0, + "log_lines": 2, + "metrics": 7 + }, + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "telemetry_sender" } -] \ No newline at end of file +] diff --git a/test/test_results/test_automode/008/biz_events.json b/test/test_results/test_automode/008/biz_events.json index 7e71d1c7..4e4e96c9 100644 --- a/test/test_results/test_automode/008/biz_events.json +++ b/test/test_results/test_automode/008/biz_events.json @@ -7,14 +7,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_automode/008", "dsoa.task.exec.status": "STARTED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "telemetry_sender" } }, { @@ -25,14 +26,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_automode/008", "dsoa.task.exec.status": "FINISHED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "telemetry_sender" } } -] +] \ No newline at end of file diff --git a/test/test_results/test_automode/008/events.json b/test/test_results/test_automode/008/events.json index ce12b84c..00b893c0 100644 --- a/test/test_results/test_automode/008/events.json +++ b/test/test_results/test_automode/008/events.json @@ -17,7 +17,8 @@ "telemetry.exporter.name": "dynatrace.snowagent", "dsoa.run.context": "test_automode/008", "eventType": "CUSTOM_INFO", - "title": "Table event data_update." + "title": "Table event data_update.", + "dsoa.run.plugin": "telemetry_sender" }, { "snowflake.event.trigger": "ddl", @@ -37,7 +38,8 @@ "telemetry.exporter.name": "dynatrace.snowagent", "dsoa.run.context": "test_automode/008", "eventType": "CUSTOM_INFO", - "title": "Table event ddl." + "title": "Table event ddl.", + "dsoa.run.plugin": "telemetry_sender" }, { "snowflake.event.trigger": "data_update", @@ -55,6 +57,7 @@ "telemetry.exporter.name": "dynatrace.snowagent", "dsoa.run.context": "test_automode/008", "eventType": "CUSTOM_INFO", - "title": "Table event data_update." + "title": "Table event data_update.", + "dsoa.run.plugin": "telemetry_sender" } ] diff --git a/test/test_results/test_automode/008/logs.json b/test/test_results/test_automode/008/logs.json index 6e9d07da..6c1fc785 100644 --- a/test/test_results/test_automode/008/logs.json +++ b/test/test_results/test_automode/008/logs.json @@ -1,9 +1,15 @@ [ { "content": "New entry to STATUS.LOG_PROCESSED_MEASUREMENTS from test_automode/008", - "entries": 2, - "metrics": 7, - "events": 3, - "dsoa.run.context": "self_monitoring" + "test_automode/008": { + "biz_events": 0, + "davis_events": 0, + "entries": 2, + "events": 3, + "log_lines": 0, + "metrics": 7 + }, + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "telemetry_sender" } -] \ No newline at end of file +] diff --git a/test/test_results/test_automode/009/biz_events.json b/test/test_results/test_automode/009/biz_events.json index b29cf0ad..13f50490 100644 --- a/test/test_results/test_automode/009/biz_events.json +++ b/test/test_results/test_automode/009/biz_events.json @@ -7,14 +7,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_automode/009", "dsoa.task.exec.status": "STARTED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "telemetry_sender" } }, { @@ -25,14 +26,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_automode/009", "dsoa.task.exec.status": "FINISHED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "telemetry_sender" } } -] +] \ No newline at end of file diff --git a/test/test_results/test_automode/009/logs.json b/test/test_results/test_automode/009/logs.json index 9ba5ba08..6df8870d 100644 --- a/test/test_results/test_automode/009/logs.json +++ b/test/test_results/test_automode/009/logs.json @@ -14,7 +14,8 @@ "k": "v", "k2": 2 }, - "dsoa.run.context": "test_automode/009" + "dsoa.run.context": "test_automode/009", + "dsoa.run.plugin": "telemetry_sender" }, { "content": "This is a test object 2", @@ -30,7 +31,8 @@ "k": 1, "k2": 2 }, - "dsoa.run.context": "test_automode/009" + "dsoa.run.context": "test_automode/009", + "dsoa.run.plugin": "telemetry_sender" }, { "content": "Log entry sent with test_automode/009", @@ -47,12 +49,20 @@ "k": false, "k2": true }, - "dsoa.run.context": "test_automode/009" + "dsoa.run.context": "test_automode/009", + "dsoa.run.plugin": "telemetry_sender" }, { "content": "New entry to STATUS.LOG_PROCESSED_MEASUREMENTS from test_automode/009", - "entries": 3, - "log_lines": 3, - "dsoa.run.context": "self_monitoring" + "test_automode/009": { + "biz_events": 0, + "davis_events": 0, + "entries": 3, + "events": 0, + "log_lines": 3, + "metrics": 0 + }, + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "telemetry_sender" } -] \ No newline at end of file +] diff --git a/test/test_results/test_automode/010/biz_events.json b/test/test_results/test_automode/010/biz_events.json index 796fc529..6a8bba94 100644 --- a/test/test_results/test_automode/010/biz_events.json +++ b/test/test_results/test_automode/010/biz_events.json @@ -7,14 +7,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_automode/010", "dsoa.task.exec.status": "STARTED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "telemetry_sender" } }, { @@ -25,14 +26,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_automode/010", "dsoa.task.exec.status": "FINISHED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "telemetry_sender" } } ] \ No newline at end of file diff --git a/test/test_results/test_automode/010/events.json b/test/test_results/test_automode/010/events.json index d460599b..01934d82 100644 --- a/test/test_results/test_automode/010/events.json +++ b/test/test_results/test_automode/010/events.json @@ -13,7 +13,8 @@ "telemetry.exporter.name": "dynatrace.snowagent", "dsoa.run.context": "test_automode/010", "eventType": "CUSTOM_INFO", - "title": "This is a test object 1" + "title": "This is a test object 1", + "dsoa.run.plugin": "telemetry_sender" }, { "status.code": "OK", @@ -30,7 +31,8 @@ "telemetry.exporter.name": "dynatrace.snowagent", "dsoa.run.context": "test_automode/010", "eventType": "PERFORMANCE_EVENT", - "title": "This is a test object 2" + "title": "This is a test object 2", + "dsoa.run.plugin": "telemetry_sender" }, { "status.code": "ERROR", @@ -47,6 +49,7 @@ "telemetry.exporter.name": "dynatrace.snowagent", "dsoa.run.context": "test_automode/010", "eventType": "ERROR_EVENT", - "title": "Event sent with test_automode/010" + "title": "Event sent with test_automode/010", + "dsoa.run.plugin": "telemetry_sender" } ] diff --git a/test/test_results/test_automode/010/logs.json b/test/test_results/test_automode/010/logs.json index bc77537b..51547de5 100644 --- a/test/test_results/test_automode/010/logs.json +++ b/test/test_results/test_automode/010/logs.json @@ -1,9 +1,15 @@ [ { "content": "New entry to STATUS.LOG_PROCESSED_MEASUREMENTS from test_automode/010", - "entries": 3, - "events": 3, - "davis_events": 3, - "dsoa.run.context": "self_monitoring" + "test_automode/010": { + "biz_events": 0, + "davis_events": 3, + "entries": 3, + "events": 3, + "log_lines": 0, + "metrics": 0 + }, + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "telemetry_sender" } -] \ No newline at end of file +] diff --git a/test/test_results/test_automode/011/biz_events.json b/test/test_results/test_automode/011/biz_events.json index de3462d8..2ee6e57f 100644 --- a/test/test_results/test_automode/011/biz_events.json +++ b/test/test_results/test_automode/011/biz_events.json @@ -7,14 +7,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_automode/011", "dsoa.task.exec.status": "STARTED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "telemetry_sender" } }, { @@ -43,7 +44,8 @@ "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "test_automode/011" + "dsoa.run.context": "test_automode/011", + "dsoa.run.plugin": "telemetry_sender" } }, { @@ -72,7 +74,8 @@ "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "test_automode/011" + "dsoa.run.context": "test_automode/011", + "dsoa.run.plugin": "telemetry_sender" } }, { @@ -101,7 +104,8 @@ "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "test_automode/011" + "dsoa.run.context": "test_automode/011", + "dsoa.run.plugin": "telemetry_sender" } }, { @@ -112,14 +116,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_automode/011", "dsoa.task.exec.status": "FINISHED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "telemetry_sender" } } ] \ No newline at end of file diff --git a/test/test_results/test_automode/011/logs.json b/test/test_results/test_automode/011/logs.json index 50cea449..3d1dc1fe 100644 --- a/test/test_results/test_automode/011/logs.json +++ b/test/test_results/test_automode/011/logs.json @@ -1,8 +1,15 @@ [ { "content": "New entry to STATUS.LOG_PROCESSED_MEASUREMENTS from test_automode/011", - "entries": 3, - "biz_events": 3, - "dsoa.run.context": "self_monitoring" + "test_automode/011": { + "biz_events": 3, + "davis_events": 0, + "entries": 3, + "events": 0, + "log_lines": 0, + "metrics": 0 + }, + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "telemetry_sender" } -] \ No newline at end of file +] diff --git a/test/test_results/test_automode/012/biz_events.json b/test/test_results/test_automode/012/biz_events.json index 19e17f4c..d58acbe8 100644 --- a/test/test_results/test_automode/012/biz_events.json +++ b/test/test_results/test_automode/012/biz_events.json @@ -7,14 +7,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_automode/012", "dsoa.task.exec.status": "STARTED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "telemetry_sender" } }, { @@ -43,7 +44,8 @@ "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "test_automode/012" + "dsoa.run.context": "test_automode/012", + "dsoa.run.plugin": "telemetry_sender" } }, { @@ -72,7 +74,8 @@ "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "test_automode/012" + "dsoa.run.context": "test_automode/012", + "dsoa.run.plugin": "telemetry_sender" } }, { @@ -101,7 +104,8 @@ "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "test_automode/012" + "dsoa.run.context": "test_automode/012", + "dsoa.run.plugin": "telemetry_sender" } }, { @@ -112,14 +116,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_automode/012", "dsoa.task.exec.status": "FINISHED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "telemetry_sender" } } ] \ No newline at end of file diff --git a/test/test_results/test_automode/012/events.json b/test/test_results/test_automode/012/events.json index ef3cfea7..906ea4ad 100644 --- a/test/test_results/test_automode/012/events.json +++ b/test/test_results/test_automode/012/events.json @@ -13,7 +13,8 @@ "telemetry.exporter.name": "dynatrace.snowagent", "dsoa.run.context": "test_automode/012", "eventType": "CUSTOM_INFO", - "title": "This is a test object 1" + "title": "This is a test object 1", + "dsoa.run.plugin": "telemetry_sender" }, { "status.code": "OK", @@ -30,7 +31,8 @@ "telemetry.exporter.name": "dynatrace.snowagent", "dsoa.run.context": "test_automode/012", "eventType": "PERFORMANCE_EVENT", - "title": "This is a test object 2" + "title": "This is a test object 2", + "dsoa.run.plugin": "telemetry_sender" }, { "status.code": "ERROR", @@ -47,6 +49,7 @@ "telemetry.exporter.name": "dynatrace.snowagent", "dsoa.run.context": "test_automode/012", "eventType": "ERROR_EVENT", - "title": "Event sent with test_automode/012" + "title": "Event sent with test_automode/012", + "dsoa.run.plugin": "telemetry_sender" } ] diff --git a/test/test_results/test_automode/012/logs.json b/test/test_results/test_automode/012/logs.json index 3059b4ab..919d42f0 100644 --- a/test/test_results/test_automode/012/logs.json +++ b/test/test_results/test_automode/012/logs.json @@ -14,7 +14,8 @@ "k": "v", "k2": 2 }, - "dsoa.run.context": "test_automode/012" + "dsoa.run.context": "test_automode/012", + "dsoa.run.plugin": "telemetry_sender" }, { "content": "This is a test object 2", @@ -30,7 +31,8 @@ "k": 1, "k2": 2 }, - "dsoa.run.context": "test_automode/012" + "dsoa.run.context": "test_automode/012", + "dsoa.run.plugin": "telemetry_sender" }, { "content": "Log entry sent with test_automode/012", @@ -47,14 +49,20 @@ "k": false, "k2": true }, - "dsoa.run.context": "test_automode/012" + "dsoa.run.context": "test_automode/012", + "dsoa.run.plugin": "telemetry_sender" }, { "content": "New entry to STATUS.LOG_PROCESSED_MEASUREMENTS from test_automode/012", - "entries": 3, - "log_lines": 3, - "events": 3, - "biz_events": 3, - "dsoa.run.context": "self_monitoring" + "test_automode/012": { + "biz_events": 3, + "davis_events": 0, + "entries": 3, + "events": 3, + "log_lines": 3, + "metrics": 0 + }, + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "telemetry_sender" } -] \ No newline at end of file +] diff --git a/test/test_results/test_automode/013/biz_events.json b/test/test_results/test_automode/013/biz_events.json index 4633012e..a9505787 100644 --- a/test/test_results/test_automode/013/biz_events.json +++ b/test/test_results/test_automode/013/biz_events.json @@ -7,14 +7,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_automode/013", "dsoa.task.exec.status": "STARTED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "telemetry_sender" } }, { @@ -43,7 +44,8 @@ "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "test_automode/013" + "dsoa.run.context": "test_automode/013", + "dsoa.run.plugin": "telemetry_sender" } }, { @@ -54,14 +56,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_automode/013", "dsoa.task.exec.status": "FINISHED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "telemetry_sender" } } -] +] \ No newline at end of file diff --git a/test/test_results/test_automode/013/events.json b/test/test_results/test_automode/013/events.json index 792e52a1..fcb0da28 100644 --- a/test/test_results/test_automode/013/events.json +++ b/test/test_results/test_automode/013/events.json @@ -13,6 +13,7 @@ "value.str": "test", "dsoa.run.context": "test_automode/013", "eventType": "CUSTOM_INFO", - "title": "This is a test object 1" + "title": "This is a test object 1", + "dsoa.run.plugin": "telemetry_sender" } ] diff --git a/test/test_results/test_automode/013/logs.json b/test/test_results/test_automode/013/logs.json index 26f93145..dd57b4c9 100644 --- a/test/test_results/test_automode/013/logs.json +++ b/test/test_results/test_automode/013/logs.json @@ -14,14 +14,20 @@ "k": "v", "k2": 2 }, - "dsoa.run.context": "test_automode/013" + "dsoa.run.context": "test_automode/013", + "dsoa.run.plugin": "telemetry_sender" }, { "content": "New entry to STATUS.LOG_PROCESSED_MEASUREMENTS from test_automode/013", - "entries": 1, - "log_lines": 1, - "events": 1, - "biz_events": 1, - "dsoa.run.context": "self_monitoring" + "test_automode/013": { + "biz_events": 1, + "davis_events": 0, + "entries": 1, + "events": 1, + "log_lines": 1, + "metrics": 0 + }, + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "telemetry_sender" } -] \ No newline at end of file +] diff --git a/test/test_results/test_automode/014/biz_events.json b/test/test_results/test_automode/014/biz_events.json index 5c7c2eb4..12846992 100644 --- a/test/test_results/test_automode/014/biz_events.json +++ b/test/test_results/test_automode/014/biz_events.json @@ -7,14 +7,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_automode/014", "dsoa.task.exec.status": "STARTED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "telemetry_sender" } }, { @@ -43,7 +44,8 @@ "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "test_automode/014" + "dsoa.run.context": "test_automode/014", + "dsoa.run.plugin": "telemetry_sender" } }, { @@ -54,14 +56,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_automode/014", "dsoa.task.exec.status": "FINISHED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "telemetry_sender" } } -] +] \ No newline at end of file diff --git a/test/test_results/test_automode/014/events.json b/test/test_results/test_automode/014/events.json index c87a2d06..4cf4396f 100644 --- a/test/test_results/test_automode/014/events.json +++ b/test/test_results/test_automode/014/events.json @@ -13,6 +13,7 @@ "value.str": "test", "dsoa.run.context": "test_automode/014", "eventType": "CUSTOM_INFO", - "title": "This is a test object 1" + "title": "This is a test object 1", + "dsoa.run.plugin": "telemetry_sender" } ] diff --git a/test/test_results/test_automode/014/logs.json b/test/test_results/test_automode/014/logs.json index 6c870fc4..5452e2f2 100644 --- a/test/test_results/test_automode/014/logs.json +++ b/test/test_results/test_automode/014/logs.json @@ -14,14 +14,20 @@ "k": "v", "k2": 2 }, - "dsoa.run.context": "test_automode/014" + "dsoa.run.context": "test_automode/014", + "dsoa.run.plugin": "telemetry_sender" }, { "content": "New entry to STATUS.LOG_PROCESSED_MEASUREMENTS from test_automode/014", - "entries": 1, - "log_lines": 1, - "events": 1, - "biz_events": 1, - "dsoa.run.context": "self_monitoring" + "test_automode/014": { + "biz_events": 1, + "davis_events": 0, + "entries": 1, + "events": 1, + "log_lines": 1, + "metrics": 0 + }, + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "telemetry_sender" } -] \ No newline at end of file +] diff --git a/test/test_results/test_budget/biz_events.json b/test/test_results/test_budget/biz_events.json index b1b87120..bce50646 100644 --- a/test/test_results/test_budget/biz_events.json +++ b/test/test_results/test_budget/biz_events.json @@ -7,14 +7,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_budget", "dsoa.task.exec.status": "STARTED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "test_budget" } }, { @@ -25,14 +26,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_budget", "dsoa.task.exec.status": "FINISHED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "test_budget" } } -] +] \ No newline at end of file diff --git a/test/test_results/test_budget/logs.json b/test/test_results/test_budget/logs.json index b9300167..4ff348fe 100644 --- a/test/test_results/test_budget/logs.json +++ b/test/test_results/test_budget/logs.json @@ -18,6 +18,7 @@ "db.namespace": "DTAGENT_DB", "snowflake.budget.name": "DTAGENT_BUDGET", "snowflake.schema.name": "APP", - "dsoa.run.context": "budgets" + "dsoa.run.context": "budgets", + "dsoa.run.plugin": "test_budget" } ] \ No newline at end of file diff --git a/test/test_results/test_connector_bizevents/biz_events.json b/test/test_results/test_connector_bizevents/biz_events.json index 46beab01..0ad9bf54 100644 --- a/test/test_results/test_connector_bizevents/biz_events.json +++ b/test/test_results/test_connector_bizevents/biz_events.json @@ -7,14 +7,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "telemetry_sender", "dsoa.task.exec.status": "STARTED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.plugin": "telemetry_sender", + "dsoa.run.context": "self_monitoring" } }, { @@ -32,6 +33,7 @@ "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", + "dsoa.run.plugin": "telemetry_sender", "dsoa.run.context": "telemetry_sender" } }, @@ -43,14 +45,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "telemetry_sender", "dsoa.task.exec.status": "FINISHED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.plugin": "telemetry_sender", + "dsoa.run.context": "self_monitoring" } } ] \ No newline at end of file diff --git a/test/test_results/test_connector_bizevents/logs.json b/test/test_results/test_connector_bizevents/logs.json index 655b14c0..af599463 100644 --- a/test/test_results/test_connector_bizevents/logs.json +++ b/test/test_results/test_connector_bizevents/logs.json @@ -1,8 +1,15 @@ [ { "content": "New entry to STATUS.LOG_PROCESSED_MEASUREMENTS from telemetry_sender", - "entries": 1, - "biz_events": 1, + "telemetry_sender": { + "biz_events": 1, + "davis_events": 0, + "entries": 1, + "events": 0, + "log_lines": 0, + "metrics": 0 + }, + "dsoa.run.plugin": "telemetry_sender", "dsoa.run.context": "self_monitoring" } ] \ No newline at end of file diff --git a/test/test_results/test_coonector_bizevents/biz_events.json b/test/test_results/test_coonector_bizevents/biz_events.json index cde1595c..6305b633 100644 --- a/test/test_results/test_coonector_bizevents/biz_events.json +++ b/test/test_results/test_coonector_bizevents/biz_events.json @@ -7,14 +7,14 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "telemetry_sender", "dsoa.task.exec.status": "STARTED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring" } }, { @@ -43,14 +43,14 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "telemetry_sender", "dsoa.task.exec.status": "FINISHED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring" } } -] +] \ No newline at end of file diff --git a/test/test_results/test_data_schemas/biz_events.json b/test/test_results/test_data_schemas/biz_events.json index 9a0ed7e0..2df7faa3 100644 --- a/test/test_results/test_data_schemas/biz_events.json +++ b/test/test_results/test_data_schemas/biz_events.json @@ -7,14 +7,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_data_schemas", "dsoa.task.exec.status": "STARTED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "test_data_schemas" } }, { @@ -25,14 +26,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_data_schemas", "dsoa.task.exec.status": "FINISHED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "test_data_schemas" } } -] +] \ No newline at end of file diff --git a/test/test_results/test_data_schemas/events.json b/test/test_results/test_data_schemas/events.json index a5f7af34..41ef2e5e 100644 --- a/test/test_results/test_data_schemas/events.json +++ b/test/test_results/test_data_schemas/events.json @@ -14,6 +14,7 @@ "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", "dsoa.run.context": "data_schemas", + "dsoa.run.plugin": "test_data_schemas", "eventType": "CUSTOM_INFO", "title": "Objects accessed by query 01b165f1-0604-1812-0040-e0030291d142 run by STEFAN.SCHWEIGER" }, @@ -33,7 +34,8 @@ "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", "dsoa.run.context": "data_schemas", + "dsoa.run.plugin": "test_data_schemas", "eventType": "CUSTOM_INFO", "title": "Objects accessed by query 01b165fb-0604-1945-0040-e0030291c3be run by STEFAN.SCHWEIGER" } -] +] \ No newline at end of file diff --git a/test/test_results/test_data_volume/biz_events.json b/test/test_results/test_data_volume/biz_events.json index d3ae90aa..3fc151b3 100644 --- a/test/test_results/test_data_volume/biz_events.json +++ b/test/test_results/test_data_volume/biz_events.json @@ -7,14 +7,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_data_volume", "dsoa.task.exec.status": "STARTED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "test_data_volume" } }, { @@ -25,14 +26,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_data_volume", "dsoa.task.exec.status": "FINISHED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "test_data_volume" } } -] +] \ No newline at end of file diff --git a/test/test_results/test_dtagent_bizevents/biz_events.json b/test/test_results/test_dtagent_bizevents/biz_events.json index b8bd3a72..9dc44033 100644 --- a/test/test_results/test_dtagent_bizevents/biz_events.json +++ b/test/test_results/test_dtagent_bizevents/biz_events.json @@ -7,14 +7,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_events", "dsoa.task.exec.status": "FINISHED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "test_send_events_directly" } } -] +] \ No newline at end of file diff --git a/test/test_results/test_dynamic_tables/biz_events.json b/test/test_results/test_dynamic_tables/biz_events.json index 77d7053d..f1babf5d 100644 --- a/test/test_results/test_dynamic_tables/biz_events.json +++ b/test/test_results/test_dynamic_tables/biz_events.json @@ -7,14 +7,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_dynamic_tables", "dsoa.task.exec.status": "STARTED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "test_dynamic_tables" } }, { @@ -25,14 +26,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_dynamic_tables", "dsoa.task.exec.status": "FINISHED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "test_dynamic_tables" } } -] +] \ No newline at end of file diff --git a/test/test_results/test_dynamic_tables/logs.json b/test/test_results/test_dynamic_tables/logs.json index 34477e1d..689c989e 100644 --- a/test/test_results/test_dynamic_tables/logs.json +++ b/test/test_results/test_dynamic_tables/logs.json @@ -15,7 +15,8 @@ "db.namespace": "DYNAMIC_TABLE_DB", "snowflake.schema.name": "DYNAMIC_TABLE_SCH", "snowflake.table.full_name": "DYNAMIC_TABLE_DB.DYNAMIC_TABLE_SCH.EMPLOYEE_DET", - "dsoa.run.context": "dynamic_tables" + "dsoa.run.context": "dynamic_tables", + "dsoa.run.plugin": "test_dynamic_tables" }, { "content": "dynamic_table_refresh_history", @@ -33,7 +34,8 @@ "db.namespace": "DYNAMIC_TABLE_DB", "snowflake.schema.name": "DYNAMIC_TABLE_SCH", "snowflake.table.full_name": "DYNAMIC_TABLE_DB.DYNAMIC_TABLE_SCH.EMPLOYEE_DET", - "dsoa.run.context": "dynamic_table_refresh_history" + "dsoa.run.context": "dynamic_table_refresh_history", + "dsoa.run.plugin": "test_dynamic_tables" }, { "content": "dynamic_table_refresh_history", @@ -51,7 +53,8 @@ "db.namespace": "DYNAMIC_TABLE_DB", "snowflake.schema.name": "DYNAMIC_TABLE_SCH", "snowflake.table.full_name": "DYNAMIC_TABLE_DB.DYNAMIC_TABLE_SCH.EMPLOYEE_DET", - "dsoa.run.context": "dynamic_table_refresh_history" + "dsoa.run.context": "dynamic_table_refresh_history", + "dsoa.run.plugin": "test_dynamic_tables" }, { "content": "dynamic_table_graph_history", @@ -77,6 +80,7 @@ "db.namespace": "DYNAMIC_TABLE_DB", "snowflake.schema.name": "DYNAMIC_TABLE_SCH", "snowflake.table.full_name": "DYNAMIC_TABLE_DB.DYNAMIC_TABLE_SCH.EMPLOYEE_DET", - "dsoa.run.context": "dynamic_table_graph_history" + "dsoa.run.context": "dynamic_table_graph_history", + "dsoa.run.plugin": "test_dynamic_tables" } -] \ No newline at end of file +] diff --git a/test/test_results/test_event_log/biz_events.json b/test/test_results/test_event_log/biz_events.json index 295362d6..f3ccff12 100644 --- a/test/test_results/test_event_log/biz_events.json +++ b/test/test_results/test_event_log/biz_events.json @@ -7,14 +7,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_event_log", "dsoa.task.exec.status": "STARTED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "test_event_log" } }, { @@ -25,14 +26,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_event_log", "dsoa.task.exec.status": "FINISHED", - "app.bundle": "self-monitoring", + "dsoa.run.plugin": "test_event_log", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring" } } -] +] \ No newline at end of file diff --git a/test/test_results/test_event_log/logs.json b/test/test_results/test_event_log/logs.json index 3c007891..3a8b6b7f 100644 --- a/test/test_results/test_event_log/logs.json +++ b/test/test_results/test_event_log/logs.json @@ -30,7 +30,8 @@ "snowflake.schema.name": "APP", "snowflake.warehouse.name": "DTAGENT_SKRUK_WH", "telemetry.sdk.language": "python", - "dsoa.run.context": "event_log_metrics" + "dsoa.run.context": "event_log_metrics", + "dsoa.run.plugin": "test_event_log" }, { "content": "event_log_metrics", @@ -63,7 +64,8 @@ "snowflake.schema.name": "APP", "snowflake.warehouse.name": "DTAGENT_SKRUK_WH", "telemetry.sdk.language": "python", - "dsoa.run.context": "event_log_metrics" + "dsoa.run.context": "event_log_metrics", + "dsoa.run.plugin": "test_event_log" }, { "content": "Invalid type dict for attribute 'snowflake.query.operator.stats' value. Expected one of ['bool', 'str', 'bytes', 'int', 'float'] or a sequence of those types", @@ -96,7 +98,8 @@ "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "event_log" + "dsoa.run.context": "event_log", + "dsoa.run.plugin": "test_event_log" }, { "content": "UPDATE state.datasources SET last_transform = '2025-02-07 12:26:07.0', last_extract = '2025-02-07 12:26:07.0', last_extract_id = 1738922400000 WHERE datasource = 'Spine.UnassignedConsumption'", @@ -115,7 +118,7 @@ "snowagent.run.context": "query_history", "snowagent.run.id": "5c0188ef23e84fb99fd31ffddd8d0dcd", "snowflake.cluster_number": 1, - "snowflake.credits.cloud_services": 4.7e-05, + "snowflake.credits.cloud_services": 0.000047, "snowflake.data.scanned": 44032, "snowflake.data.scanned_from_cache": 1, "snowflake.data.written": 22016, @@ -179,6 +182,7 @@ "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "event_log" + "dsoa.run.context": "event_log", + "dsoa.run.plugin": "test_event_log" } -] \ No newline at end of file +] diff --git a/test/test_results/test_event_log/spans.json b/test/test_results/test_event_log/spans.json index b0f5fe1f..29f0ea8d 100644 --- a/test/test_results/test_event_log/spans.json +++ b/test/test_results/test_event_log/spans.json @@ -24,6 +24,7 @@ "snowflake.warehouse.name": "DTAGENT_SKRUK_WH", "telemetry.sdk.language": "sql", "dsoa.run.context": "event_log_spans", + "dsoa.run.plugin": "test_event_log", "dsoa.debug.span.events.added": 0, "dsoa.debug.span.events.failed": 0 }, @@ -52,6 +53,7 @@ "snowflake.warehouse.name": "DTAGENT_SKRUK_WH", "telemetry.sdk.language": "sql", "dsoa.run.context": "event_log_spans", + "dsoa.run.plugin": "test_event_log", "dsoa.debug.span.events.added": 0, "dsoa.debug.span.events.failed": 0 } diff --git a/test/test_results/test_event_usage/biz_events.json b/test/test_results/test_event_usage/biz_events.json index 44b7c4e5..98ed59d7 100644 --- a/test/test_results/test_event_usage/biz_events.json +++ b/test/test_results/test_event_usage/biz_events.json @@ -7,14 +7,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_event_usage", "dsoa.task.exec.status": "STARTED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "test_event_usage" } }, { @@ -25,14 +26,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_event_usage", "dsoa.task.exec.status": "FINISHED", - "app.bundle": "self-monitoring", + "dsoa.run.plugin": "test_event_usage", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring" } } -] +] \ No newline at end of file diff --git a/test/test_results/test_event_usage/logs.json b/test/test_results/test_event_usage/logs.json index ce8a5210..8f0be0cd 100644 --- a/test/test_results/test_event_usage/logs.json +++ b/test/test_results/test_event_usage/logs.json @@ -3,11 +3,13 @@ "content": "Event Usage", "snowflake.credits.used": 0.001007024, "snowflake.data.ingested": 736, - "dsoa.run.context": "event_usage" + "dsoa.run.context": "event_usage", + "dsoa.run.plugin": "test_event_usage" }, { "content": "Event Usage", "snowflake.credits.used": 0.000215595, - "dsoa.run.context": "event_usage" + "dsoa.run.context": "event_usage", + "dsoa.run.plugin": "test_event_usage" } -] \ No newline at end of file +] diff --git a/test/test_results/test_login_history/biz_events.json b/test/test_results/test_login_history/biz_events.json index 0614c469..dd026d73 100644 --- a/test/test_results/test_login_history/biz_events.json +++ b/test/test_results/test_login_history/biz_events.json @@ -7,14 +7,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_login_history", "dsoa.task.exec.status": "STARTED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "test_login_history" } }, { @@ -25,14 +26,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_login_history", "dsoa.task.exec.status": "FINISHED", - "app.bundle": "self-monitoring", + "dsoa.run.plugin": "test_login_history", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring" } } -] +] \ No newline at end of file diff --git a/test/test_results/test_login_history/logs.json b/test/test_results/test_login_history/logs.json index 95ddfd36..f389db06 100644 --- a/test/test_results/test_login_history/logs.json +++ b/test/test_results/test_login_history/logs.json @@ -9,7 +9,8 @@ "client.type": "OTHER", "db.user": "SEBASTIAN.KRUK", "event.name": "LOGIN", - "dsoa.run.context": "login_history" + "dsoa.run.context": "login_history", + "dsoa.run.plugin": "test_login_history" }, { "content": "login_history", @@ -21,6 +22,7 @@ "client.type": "OTHER", "db.user": "SNOWAGENT_ADMIN", "event.name": "LOGIN", - "dsoa.run.context": "login_history" + "dsoa.run.context": "login_history", + "dsoa.run.plugin": "test_login_history" } -] \ No newline at end of file +] diff --git a/test/test_results/test_query_history/biz_events.json b/test/test_results/test_query_history/biz_events.json index 807ca632..47bcf2e9 100644 --- a/test/test_results/test_query_history/biz_events.json +++ b/test/test_results/test_query_history/biz_events.json @@ -7,14 +7,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_query_history", "dsoa.task.exec.status": "STARTED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "test_query_history" } }, { @@ -25,14 +26,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_query_history", "dsoa.task.exec.status": "FINISHED", - "app.bundle": "self-monitoring", + "dsoa.run.plugin": "test_query_history", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring" } } -] +] \ No newline at end of file diff --git a/test/test_results/test_query_history/logs.json b/test/test_results/test_query_history/logs.json index 8dff1766..817a4641 100644 --- a/test/test_results/test_query_history/logs.json +++ b/test/test_results/test_query_history/logs.json @@ -1,7 +1,7 @@ [ { "content": "CALL DTAGENT_DB.APP.F_ACTIVE_QUERIES_INSTRUMENTED();\n", - "snowflake.credits.cloud_services": 1e-05, + "snowflake.credits.cloud_services": 0.00001, "snowflake.data.written_to_result": 640, "snowflake.load.used": 100, "snowflake.rows.written_to_result": 798, @@ -32,11 +32,12 @@ "snowflake.query.execution_status": "SUCCESS", "snowflake.role.name": "DTAGENT_ADMIN", "snowflake.warehouse.name": "DTAGENT_WH", - "dsoa.run.context": "query_history" + "dsoa.run.context": "query_history", + "dsoa.run.plugin": "test_query_history" }, { "content": "with cte_all_queries as (\n (\n select * from TABLE(DTAGENT_DB.APP.F_GET_RUNNING_QUERIES())\n )\n union all\n (\n select * from TABLE(DTAGENT_DB.APP.F_GET_FINISHED_QUERIES())\n where END_TIME > DTAGENT_DB.APP.F_LAST_PROCESSED_TS('active_queries')\n )\n )\n , cte_active_queries as (\n select \n START_TIME,\n END_TIME,\n\n QUERY_ID,\n SESSION_ID,\n DATABASE_NAME,\n SCHEMA_NAME,\n\n QUERY_TEXT,\n QUERY_TYPE,\n QUERY_TAG,\n QUERY_HASH,\n QUERY_HASH_VERSION,\n QUERY_PARAMETERIZED_HASH,\n QUERY_PARAMETERIZED_HASH_VERSION,\n\n USER_NAME,\n ROLE_NAME,\n\n WAREHOUSE_NAME,\n WAREHOUSE_TYPE,\n\n EXECUTION_STATUS,\n ERROR_CODE,\n ERROR_MESSAGE,\n\n // metrics\n RUNNING_TIME,\n EXECUTION_TIME,\n COMPILATION_TIME,\n TOTAL_ELAPSED_TIME,\n BYTES_WRITTEN_TO_RESULT,\n ROWS_WRITTEN_TO_RESULT,\n from cte_all_queries aq\n where\n ( array_size(DTAGENT_DB.APP.F_GET_CONFIG_VALUE('plugins.active_queries.report_execution_status', [])) = 0\n or array_contains(EXECUTION_STATUS::variant, DTAGENT_DB.APP.F_GET_CONFIG_VALUE('plugins.active_queries.report_execution_status', [])::array) )\n )\n select \n qh.END_TIME::timestamp_ltz as TIMESTAMP,\n\n qh.query_id as QUERY_ID,\n qh.session_id as SESSION_ID,\n\n CONCAT(\n 'SQL query ',\n qh.execution_status,\n ' at ',\n COALESCE(qh.database_name, '')\n ) as NAME,\n NAME as _MESSAGE,\n\n \n extract(epoch_nanosecond from qh.start_time) as START_TIME,\n extract(epoch_nanosecond from qh.end_time) as END_TIME,\n\n \n OBJECT_CONSTRUCT(\n 'db.namespace', qh.database_name,\n 'snowflake.warehouse.name', qh.warehouse_name,\n 'db.user', qh.user_name,\n 'snowflake.role.name', qh.role_name,\n 'snowflake.query.execution_status', qh.execution_status\n ) as DIMENSIONS,\n \n OBJECT_CONSTRUCT(\n 'db.query.text', qh.query_text,\n 'db.operation.name', qh.query_type,\n 'session.id', qh.session_id,\n 'snowflake.query.id', qh.query_id,\n 'snowflake.query.tag', qh.query_tag,\n 'snowflake.query.hash', qh.query_hash,\n 'snowflake.query.hash_version', qh.query_hash_version,\n 'snowflake.query.parametrized_hash', qh.query_parameterized_hash,\n 'snowflake.query.parametrized_hash_version', qh.query_parameterized_hash_version,\n 'snowflake.error.code', qh.error_code,\n 'snowflake.error.message', qh.error_message,\n 'snowflake.warehouse.type', qh.warehouse_type,\n 'snowflake.schema.name', qh.schema_name\n ) as ATTRIBUTES,\n \n OBJECT_CONSTRUCT(\n 'snowflake.time.running', qh.running_time,\n 'snowflake.time.execution', qh.execution_time,\n 'snowflake.time.compilation', qh.compilation_time,\n 'snowflake.time.total_elapsed', qh.total_elapsed_time,\n 'snowflake.data.written_to_result', qh.bytes_written_to_result,\n 'snowflake.rows.written_to_result', qh.rows_written_to_result\n ) as METRICS\n from \n cte_active_queries qh\n order by \n TIMESTAMP asc", - "snowflake.credits.cloud_services": 2.7e-05, + "snowflake.credits.cloud_services": 0.000027, "snowflake.data.written_to_result": 640, "snowflake.load.used": 100, "snowflake.rows.written_to_result": 798, @@ -76,11 +77,12 @@ "snowflake.query.execution_status": "SUCCESS", "snowflake.role.name": "DTAGENT_ADMIN", "snowflake.warehouse.name": "DTAGENT_WH", - "dsoa.run.context": "query_history" + "dsoa.run.context": "query_history", + "dsoa.run.plugin": "test_query_history" }, { "content": "with cte_all_queries as (\n (\n select * from TABLE(result_scan(:QID_0))\n )\n union all\n (\n select * from TABLE(result_scan(:QID_1))\n where END_TIME > DTAGENT_DB.APP.F_LAST_PROCESSED_TS('active_queries')\n )\n )\n , cte_active_queries as (\n select \n START_TIME,\n END_TIME,\n\n QUERY_ID,\n SESSION_ID,\n DATABASE_NAME,\n SCHEMA_NAME,\n\n QUERY_TEXT,\n QUERY_TYPE,\n QUERY_TAG,\n QUERY_HASH,\n QUERY_HASH_VERSION,\n QUERY_PARAMETERIZED_HASH,\n QUERY_PARAMETERIZED_HASH_VERSION,\n\n USER_NAME,\n ROLE_NAME,\n\n WAREHOUSE_NAME,\n WAREHOUSE_TYPE,\n\n EXECUTION_STATUS,\n ERROR_CODE,\n ERROR_MESSAGE,\n\n // metrics\n RUNNING_TIME,\n EXECUTION_TIME,\n COMPILATION_TIME,\n TOTAL_ELAPSED_TIME,\n BYTES_WRITTEN_TO_RESULT,\n ROWS_WRITTEN_TO_RESULT,\n from cte_all_queries aq\n where\n ( array_size(DTAGENT_DB.APP.F_GET_CONFIG_VALUE('plugins.active_queries.report_execution_status', [])) = 0\n or array_contains(EXECUTION_STATUS::variant, DTAGENT_DB.APP.F_GET_CONFIG_VALUE('plugins.active_queries.report_execution_status', [])::array) )\n )\n select \n qh.END_TIME::timestamp_ltz as TIMESTAMP,\n\n qh.query_id as QUERY_ID,\n qh.session_id as SESSION_ID,\n\n CONCAT(\n 'SQL query ',\n qh.execution_status,\n ' at ',\n COALESCE(qh.database_name, '')\n ) as NAME,\n NAME as _MESSAGE,\n\n \n extract(epoch_nanosecond from qh.start_time) as START_TIME,\n extract(epoch_nanosecond from qh.end_time) as END_TIME,\n\n \n OBJECT_CONSTRUCT(\n 'db.namespace', qh.database_name,\n 'snowflake.warehouse.name', qh.warehouse_name,\n 'db.user', qh.user_name,\n 'snowflake.role.name', qh.role_name,\n 'snowflake.query.execution_status', qh.execution_status\n ) as DIMENSIONS,\n \n OBJECT_CONSTRUCT(\n 'db.query.text', qh.query_text,\n 'db.operation.name', qh.query_type,\n 'session.id', qh.session_id,\n 'snowflake.query.id', qh.query_id,\n 'snowflake.query.tag', qh.query_tag,\n 'snowflake.query.hash', qh.query_hash,\n 'snowflake.query.hash_version', qh.query_hash_version,\n 'snowflake.query.parametrized_hash', qh.query_parameterized_hash,\n 'snowflake.query.parametrized_hash_version', qh.query_parameterized_hash_version,\n 'snowflake.error.code', qh.error_code,\n 'snowflake.error.message', qh.error_message,\n 'snowflake.warehouse.type', qh.warehouse_type,\n 'snowflake.schema.name', qh.schema_name\n ) as ATTRIBUTES,\n \n OBJECT_CONSTRUCT(\n 'snowflake.time.running', qh.running_time,\n 'snowflake.time.execution', qh.execution_time,\n 'snowflake.time.compilation', qh.compilation_time,\n 'snowflake.time.total_elapsed', qh.total_elapsed_time,\n 'snowflake.data.written_to_result', qh.bytes_written_to_result,\n 'snowflake.rows.written_to_result', qh.rows_written_to_result\n ) as METRICS\n from \n cte_active_queries qh\n order by \n TIMESTAMP asc", - "snowflake.credits.cloud_services": 9.2e-05, + "snowflake.credits.cloud_services": 0.000092, "snowflake.data.scanned": 5640704, "snowflake.data.written_to_result": 117512, "snowflake.load.used": 100, @@ -124,6 +126,7 @@ "snowflake.query.execution_status": "SUCCESS", "snowflake.role.name": "DTAGENT_ADMIN", "snowflake.warehouse.name": "DTAGENT_WH", - "dsoa.run.context": "query_history" + "dsoa.run.context": "query_history", + "dsoa.run.plugin": "test_query_history" } -] \ No newline at end of file +] diff --git a/test/test_results/test_query_history/spans.json b/test/test_results/test_query_history/spans.json index 8e8ed824..1ae8636b 100644 --- a/test/test_results/test_query_history/spans.json +++ b/test/test_results/test_query_history/spans.json @@ -73,6 +73,7 @@ "snowflake.role.name": "DTAGENT_ADMIN", "snowflake.warehouse.name": "DTAGENT_WH", "dsoa.run.context": "query_history", + "dsoa.run.plugin": "test_query_history", "dsoa.debug.span.events.added": 0, "dsoa.debug.span.events.failed": 0 }, @@ -150,6 +151,7 @@ "snowflake.role.name": "DTAGENT_ADMIN", "snowflake.warehouse.name": "DTAGENT_WH", "dsoa.run.context": "query_history", + "dsoa.run.plugin": "test_query_history", "dsoa.debug.span.events.added": 0, "dsoa.debug.span.events.failed": 0 }, @@ -218,6 +220,7 @@ "snowflake.role.name": "DTAGENT_ADMIN", "snowflake.warehouse.name": "DTAGENT_WH", "dsoa.run.context": "query_history", + "dsoa.run.plugin": "test_query_history", "dsoa.debug.span.events.added": 0, "dsoa.debug.span.events.failed": 0 } diff --git a/test/test_results/test_resource_monitors/biz_events.json b/test/test_results/test_resource_monitors/biz_events.json index cc70d390..b2041ace 100644 --- a/test/test_results/test_resource_monitors/biz_events.json +++ b/test/test_results/test_resource_monitors/biz_events.json @@ -7,14 +7,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_resource_monitors", "dsoa.task.exec.status": "STARTED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "test_resource_monitors" } }, { @@ -25,14 +26,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_resource_monitors", "dsoa.task.exec.status": "FINISHED", - "app.bundle": "self-monitoring", + "dsoa.run.plugin": "test_resource_monitors", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring" } } -] +] \ No newline at end of file diff --git a/test/test_results/test_send_davis_events_directly/davis_events.json b/test/test_results/test_send_davis_events_directly/davis_events.json index 6ef73885..15523ce9 100644 --- a/test/test_results/test_send_davis_events_directly/davis_events.json +++ b/test/test_results/test_send_davis_events_directly/davis_events.json @@ -75,6 +75,7 @@ "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", + "dsoa.run.plugin": "test_send_events_directly", "dsoa.run.context": "data_volume" } } diff --git a/test/test_results/test_send_generic_events_directly/events.json b/test/test_results/test_send_generic_events_directly/events.json index 6a596e10..5a6ad413 100644 --- a/test/test_results/test_send_generic_events_directly/events.json +++ b/test/test_results/test_send_generic_events_directly/events.json @@ -63,7 +63,8 @@ "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", "dsoa.run.context": "data_volume", + "dsoa.run.plugin": "test_send_events_directly", "eventType": "CUSTOM_DEPLOYMENT", "title": "Dynatrace Snowflake Observability Agent test event 6" } -] +] \ No newline at end of file diff --git a/test/test_results/test_send_results_as_bizevents/biz_events.json b/test/test_results/test_send_results_as_bizevents/biz_events.json index e0930b5f..05b47704 100644 --- a/test/test_results/test_send_results_as_bizevents/biz_events.json +++ b/test/test_results/test_send_results_as_bizevents/biz_events.json @@ -18,7 +18,8 @@ "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "data_volume" + "dsoa.run.context": "data_volume", + "dsoa.run.plugin": "test_send_results_as_bizevents" } }, { @@ -42,7 +43,8 @@ "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "data_volume" + "dsoa.run.context": "data_volume", + "dsoa.run.plugin": "test_send_results_as_bizevents" } } -] +] \ No newline at end of file diff --git a/test/test_results/test_shares/biz_events.json b/test/test_results/test_shares/biz_events.json index ebab4a16..67f55349 100644 --- a/test/test_results/test_shares/biz_events.json +++ b/test/test_results/test_shares/biz_events.json @@ -7,14 +7,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_shares", "dsoa.task.exec.status": "STARTED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "test_shares" } }, { @@ -25,14 +26,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_shares", "dsoa.task.exec.status": "FINISHED", - "app.bundle": "self-monitoring", + "dsoa.run.plugin": "test_shares", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring" } } -] +] \ No newline at end of file diff --git a/test/test_results/test_shares/logs.json b/test/test_results/test_shares/logs.json index 2d012a6c..b516824b 100644 --- a/test/test_results/test_shares/logs.json +++ b/test/test_results/test_shares/logs.json @@ -15,7 +15,8 @@ "db.namespace": "DATA_SCIENTIST_DEV_DB", "snowflake.grant.name": "DATA_SCIENTIST_DEV_DB", "snowflake.share.name": "DATA_SCIENTIST_DEVEL_DS_CI360_SHARE", - "dsoa.run.context": "outbound_shares" + "dsoa.run.context": "outbound_shares", + "dsoa.run.plugin": "test_shares" }, { "content": "Outbound share details for DATA_SCIENTIST_DEVEL_DS_CI360_SHARE", @@ -33,7 +34,8 @@ "db.namespace": "DATA_SCIENTIST_DEV_DB", "snowflake.grant.name": "DATA_SCIENTIST_DEV_DB.ACCOUNT_EXPERIENCE", "snowflake.share.name": "DATA_SCIENTIST_DEVEL_DS_CI360_SHARE", - "dsoa.run.context": "outbound_shares" + "dsoa.run.context": "outbound_shares", + "dsoa.run.plugin": "test_shares" }, { "content": "Inbound share details for BIET_MONITORING_SHARE", @@ -42,7 +44,8 @@ "snowflake.share.shared_from": "WMBJBCQ.CI360TESTACCOUNT", "db.namespace": "CI360_SHARE_MONITORING_DB", "snowflake.share.name": "BIET_MONITORING_SHARE", - "dsoa.run.context": "inbound_shares" + "dsoa.run.context": "inbound_shares", + "dsoa.run.plugin": "test_shares" }, { "content": "Inbound share details for BIET_MONITORING_SHARE", @@ -51,6 +54,7 @@ "snowflake.share.shared_from": "WMBJBCQ.DYNATRACEDIGITALBUSINESSDW", "db.namespace": "DT_SHARE_MONITORING_DB", "snowflake.share.name": "BIET_MONITORING_SHARE", - "dsoa.run.context": "inbound_shares" + "dsoa.run.context": "inbound_shares", + "dsoa.run.plugin": "test_shares" } -] \ No newline at end of file +] diff --git a/test/test_results/test_tasks/biz_events.json b/test/test_results/test_tasks/biz_events.json index 08edbccb..adee80cc 100644 --- a/test/test_results/test_tasks/biz_events.json +++ b/test/test_results/test_tasks/biz_events.json @@ -7,14 +7,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_tasks", "dsoa.task.exec.status": "STARTED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "test_tasks" } }, { @@ -25,14 +26,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_tasks", "dsoa.task.exec.status": "FINISHED", - "app.bundle": "self-monitoring", + "dsoa.run.plugin": "test_tasks", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring" } } -] +] \ No newline at end of file diff --git a/test/test_results/test_tasks/logs.json b/test/test_results/test_tasks/logs.json index 1656d19d..50564054 100644 --- a/test/test_results/test_tasks/logs.json +++ b/test/test_results/test_tasks/logs.json @@ -12,7 +12,8 @@ "db.namespace": "DTAGENT_DB", "snowflake.schema.name": "APP", "snowflake.task.name": "TASK_DTAGENT_USERS", - "dsoa.run.context": "task_history" + "dsoa.run.context": "task_history", + "dsoa.run.plugin": "test_tasks" }, { "content": "New Tasks History entry for DTAGENT_DB", @@ -27,6 +28,7 @@ "db.namespace": "DTAGENT_DB", "snowflake.schema.name": "APP", "snowflake.task.name": "TASK_DTAGENT_DATA_SCHEMAS", - "dsoa.run.context": "task_history" + "dsoa.run.context": "task_history", + "dsoa.run.plugin": "test_tasks" } -] \ No newline at end of file +] diff --git a/test/test_results/test_trust_center/biz_events.json b/test/test_results/test_trust_center/biz_events.json index 31711418..cf33eee5 100644 --- a/test/test_results/test_trust_center/biz_events.json +++ b/test/test_results/test_trust_center/biz_events.json @@ -7,14 +7,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_trust_center", "dsoa.task.exec.status": "STARTED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "test_trust_center" } }, { @@ -25,14 +26,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_trust_center", "dsoa.task.exec.status": "FINISHED", - "app.bundle": "self-monitoring", + "dsoa.run.plugin": "test_trust_center", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring" } } -] +] \ No newline at end of file diff --git a/test/test_results/test_trust_center/logs.json b/test/test_results/test_trust_center/logs.json index 90043445..6e6f2e31 100644 --- a/test/test_results/test_trust_center/logs.json +++ b/test/test_results/test_trust_center/logs.json @@ -14,7 +14,8 @@ "snowflake.trust_center.scanner.package.id": "SECURITY_ESSENTIALS", "snowflake.trust_center.scanner.type": "Vulnerability", "vulnerability.risk.level": "MEDIUM", - "dsoa.run.context": "trust_center" + "dsoa.run.context": "trust_center", + "dsoa.run.plugin": "test_trust_center" }, { "content": "TrustCenter event: [CRITICAL] 3.1 Ensure that an account-level network policy has been configured to only allow access from trusted IP addresses", @@ -31,6 +32,7 @@ "snowflake.trust_center.scanner.package.id": "SECURITY_ESSENTIALS", "snowflake.trust_center.scanner.type": "Vulnerability", "vulnerability.risk.level": "CRITICAL", - "dsoa.run.context": "trust_center" + "dsoa.run.context": "trust_center", + "dsoa.run.plugin": "test_trust_center" } -] \ No newline at end of file +] diff --git a/test/test_results/test_users/biz_events.json b/test/test_results/test_users/biz_events.json index 17c8b6d5..fdcd609d 100644 --- a/test/test_results/test_users/biz_events.json +++ b/test/test_results/test_users/biz_events.json @@ -7,14 +7,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_users", "dsoa.task.exec.status": "STARTED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "test_users" } }, { @@ -25,14 +26,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_users", "dsoa.task.exec.status": "FINISHED", - "app.bundle": "self-monitoring", + "dsoa.run.plugin": "test_users", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring" } } -] +] \ No newline at end of file diff --git a/test/test_results/test_users/logs.json b/test/test_results/test_users/logs.json index b9c4b59f..3f4724c4 100644 --- a/test/test_results/test_users/logs.json +++ b/test/test_results/test_users/logs.json @@ -10,7 +10,8 @@ "snowflake.user.owner": "SECURITYADMIN", "snowflake.user.password_last_set_time": 1720426231840000000, "db.user": "TERRAFORM_USER", - "dsoa.run.context": "users" + "dsoa.run.context": "users", + "dsoa.run.plugin": "test_users" }, { "content": "User details for TEST_PIPELINE", @@ -26,21 +27,24 @@ "snowflake.user.owner": "SECURITYADMIN", "snowflake.user.password_last_set_time": 1679517316030000000, "db.user": "TEST_PIPELINE", - "dsoa.run.context": "users" + "dsoa.run.context": "users", + "dsoa.run.plugin": "test_users" }, { "content": "User direct roles removed since 1970-01-01 00:00:00.000 Z", "snowflake.user.roles.direct.removed": "SCRATCHPAD_ROLESCRATCHPAD_ROLESCRATCHPAD_ROLE", "snowflake.user.roles.direct.removed_on": 1621598400000000000, "db.user": "DEV_SF_BI_MODELER", - "dsoa.run.context": "users" + "dsoa.run.context": "users", + "dsoa.run.plugin": "test_users" }, { "content": "User direct roles removed since 1970-01-01 00:00:00.000 Z", "snowflake.user.roles.direct.removed": "DEVEL_PIPELINE_ROLE", "snowflake.user.roles.direct.removed_on": 1622116800000000000, "db.user": "DEVEL_PIPELINE", - "dsoa.run.context": "users" + "dsoa.run.context": "users", + "dsoa.run.plugin": "test_users" }, { "content": "users", @@ -50,7 +54,8 @@ ], "snowflake.user.roles.last_altered": 1615219847000000000, "db.user": "ARTURBORGATTO", - "dsoa.run.context": "users" + "dsoa.run.context": "users", + "dsoa.run.plugin": "test_users" }, { "content": "users", @@ -60,7 +65,8 @@ ], "snowflake.user.roles.last_altered": 1649326499175000000, "db.user": "TERRAFORM_USER", - "dsoa.run.context": "users" + "dsoa.run.context": "users", + "dsoa.run.plugin": "test_users" }, { "content": "users", @@ -71,7 +77,8 @@ "snowflake.user.privilege.grants": "FACT_HOSTS,TMP_DEMO_LOCAL_TEMPORARY,DIM_ENVIRONMENT,CDH_MAINFRAME_MSU_HISTORY,CDH_DDU_METRICS_BY_METRIC_HISTORY,CDH_DDU_TRACES_BY_ENTITY_HISTORY,CDH_ODIN_AGENT_HISTORY,CDH_DEEP_MONITORING_SETTINGS_HISTORY,DIM_PRODUCT,DISCOVERED_CLOUD_SERVICES_REPORT,CDH_SERVICE_HISTORY,FACT_ENTITY_TAG_COVERAGE,CDH_COMPETITOR_JS_FRAMEWORK_USAGE_HISTORY,FACT_API_USER_AGENT_USAGE,DIM_EXTENSION,TENANT_STATUS,CDH_PROBLEM_EVENT_METADATA_HISTORY,CDH_CUSTOM_SESSIONS_APPLICATION_TECHNOLOGY_BILLING_TYPE_HISTORY,CDH_DDU_TRACES_BY_DESCRIPTION_HISTORY,CDH_PROBLEM_ROOT_CAUSE_GROUP_HISTORY,DIM_DEVICE_TYPE,DIM_PROCESS_GROUP,DC_JIRA_REQUESTS,FACT_COLUMN_PROTECTION,CDH_CONTAINER_GROUP_HISTORY,SFDC_PROJECT,CDH_CLUSTER_NETWORK_ZONE_STATS_HISTORY,DIM_HOST,REPORTS_EXECUTION_LOG,DIM_PROBLEM_EVENT_STATUS,CDH_JS_FRAMEWORK_USAGE_HISTORY,FACT_CUSTOMER_ACCOUNTS,DAVIS_CHANNEL_CONFIGURATION,CDH_DEEP_MONITORING_SETTINGS_FEATURES_HISTORY,FACT_CF_FOUNDATIONS,CDH_INTERNAL_ENTITY_MODEL_CAPPING_INFORMATION_HISTORY,R,BAS_AUDIT_FIELD,DIM_CLOUD_APPLICATION_INSTANCE_TYPE,WOOPRA_PAGEVIEW,DIM_CLOUD_APPLICATION_TYPE,DIM_SESSION_CITY,DIM_AREA,BILLING_USAGE,RUM_PAGEVIEW,TIM,FACT_CLOUD_APPLICATION_INSTANCES,DIM_SESSION_REGION,BAS_USER,FACT_TABLE_USAGE,DAVIS_USER,DIM_AGENT_ATTRIBUTES,ALECKI_INT,MANAGED_CLUSTER,DIM_HOST_ATTRIBUTES_HISTORY,CONTRACT,CDH_TOTAL_FDI_EVENT_COUNT_HISTORY,TENANT_LICENSE,DAVIS_USAGE,ENVIRONMENT_USAGE_DAILY_SUMMARY_VIEW,DIM_DEM_GOALS,FACT_PROBLEMS,DIM_USAGE_TYPE,INFRASTRUCTURE_SOLUTION_ACCOUNTS,INTERCOM_CONVERSATION_PARTS,CDH_SESSION_STORAGE_USAGE_HISTORY,ALECKI_ALL,CDH_METRIC_EVENT_CONFIG_THRESHOLD_BASED_MODEL_HISTORY,Z,CDH_FEATURE_FLAG_HISTORY,SFDC_ACCOUNT,PRIMKEY,CDH_METRIC_QUERY_STATS_HISTORY,ALECKI_VARCHAR,CDH_SYNTHETIC_MONITOR_LOCATION_HISTORY,PARTNER_REFERRAL,FACT_OPPORTUNITIES,EMPLOYEE_COUNT,CDH_BILLING_APP_SESSIONS_HISTORY,TENANT,DIM_PRODUCT_USER,SQL_LOG,TENANT_LAST_ACCESS_DATE,FACT_ACTIVE_GATE_UPDATE_STATUS,DIM_CLOUD_APPLICATION_NAMESPACE,DIM_OPPORTUNITY_STAGE,BI_STATUS,FACT_AGENT_TECHNOLOGIES,DIM_ACTIVE_GATE,ALECKI_DATE,CDH_ACTIVE_GATE_MODULES_STATUSES_HISTORY,CDH_ODIN_AGENT_ME_IDENTIFIER_HISTORY,DIM_API_ENDPOINT,DEF_EXAMPLE,CDH_TENANT_NETWORK_ZONE_STATS_HISTORY,FACT_APPLICATIONS,CDH_PLUGIN_METRIC_STATS_HISTORY,CDH_TAG_COVERAGE_HISTORY,TYPES,DIM_QUALITY_TYPE,DIM_ENVIRONMENT_ATTRIBUTES,CDH_SOFTWARE_COMPONENT_DETAILS_EVIDENCE_HISTORY,DIM_KUBERNETES_CLUSTER,CDH_SOFTWARE_COMPONENT_DETAILS_HISTORY,FACT_TAG_COVERAGE,DIM_PRODUCT_BEHAVIORAL_EVENT,CDH_REQUEST_ATTRIBUTE_STATS_HISTORY,FACT_CONTRACT_USAGE,CDH_SECURITY_PROBLEM_HISTORY,DIM_AGENT,TENANT_USAGE_DAILY_SUMMARY,TENANT_USAGE_DAILY_SUMMARY_VIEW,FACT_API_USAGE_AGGR,FACT_PRODUCT_PAGE_VIEWS,DIM_DT_ACCOUNT,FACT_PROCESS_TECHNOLOGIES,DIM_POWERBI_COLUMN,CDH_TILE_FILTER_CONFIG_HISTORY,CDH_APPLICATION_HISTORY,CDH_ENVIRONMENT_RAW,CDH_PROBLEM_RANKED_ENTITY_HISTORY,ALECKI_DECIMAL,ACCOUNT_STATUS,DIM_CUSTOMER,CDH_SYNTHETIC_MONITOR_HISTORY,DIM_CLUSTER_ATTRIBUTES,MONTHLY_CONSUMPTION_EXT,CDH_FDI_EVENT_INSTANCE_CLASSES_HISTORY,CDH_CUSTOM_SESSIONS_APPLICATION_TECHNOLOGY_TYPE_HISTORY,DIM_GEOGRAPHY,FACT_CUSTOMER_SUPPORT,CDH_METRIC_EVENT_CONFIG_NAME_FILTER_HISTORY,COMPANY,CDH_CONTAINER_MEMORY_USAGE_HISTORY,DIM_PRODUCT_PAGE,DEC,CDH_LOG_MONITORING_STATS_HISTORY,DIM_ACTIVE_GATE_MODULE,DIM_VERSION,CDH_CF_FOUNDATION_HOST_HISTORY,INTERCOM_COMPANIES,CDH_CLOUD_APPLICATION_INSTANCE_HISTORY,HASHED_VALUES,DIM_POC,CDH_CONTAINER_GROUP_INSTANCE_HISTORY,DIM_CF_FOUNDATION,CDH_VULNERABILITY_MATCHING_METADATA_HISTORY,AUTOPROV_EVENTS_FEATURES,DIM_COUNTRY,CDH_METRIC_EVENT_CONFIG_HISTORY,DIM_TRIAL,CDH_DATABASE_INSIGHTS_ENDPOINT_DETAILS_HISTORY,FACT_CONTRACT_LATEST_USAGE,DIM_METRIC,CONTRACT_BILLING_INFO,DIM_ACTIVE_GATE_TYPE,DIM_DT_ACCOUNT_ATTRIBUTES,CDH_FDI_EVENT_METADATA_HISTORY,CDH_MOBILE_AGENT_VERSION_USAGE_HISTORY,RUM_BEHAVIORAL_EVENT_PROPERTIES,FACT_CONTAINER_GROUP_INSTANCES,CDH_MOBILE_CRASHES_BY_RETRIEVAL_DELAY_HISTORY,CDH_VIRTUALIZATION_HISTORY,CDH_ALERTING_PROFILE_HISTORY,CDH_DEEP_MONITORING_SETTINGS_FEATURE_V2_HISTORY,TENANT_USAGE,BILLING_PROVIDER,CDH_CLUSTER_HISTORY,REGION,MONTHLY_USAGE,DIM_CONTAINERIZATION_TYPE,CDH_ACTIVE_GATE_HISTORY,BI_TEST_5K,CDH_DASHBOARD_CONFIG_HISTORY,ALECKI_MIXT,DIM_POWERBI_MEASURE,DIM_VERSIONED_MODULE,CDH_FDI_EVENT_TYPE_AGGREGATIONS_HISTORY,CDH_PROBLEM_EVIDENCE_HISTORY_ARCHIVE,TABLE_LOAD_INFO,FACT_PRODUCT_PAGE_VIEWS_DAILY_AGGR,SQL_LOG_PIPELINE,BI_TEST_16M,SFDC_TENANT,PROMO_USAGE,CDH_CONDITIONAL_PROCEDURES_RULES_HISTORY,FACT_USER_GROUP_MAP,CDH_DASHBOARD_CONFIG_TILE_HISTORY,QUERY_STATS,TIME_ZONE,CDH_CLUSTER_TAGS_HISTORY,CDH_LOG_MONITORING_METRIC_STATS_HISTORY,DIM_VERBATIM_TYPE,DIM_REGION,CDH_UEM_CONFIG_PROPERTY_TAG_HISTORY,DIM_PROBLEM,CDH_DISCOVERED_VIRTUALIZATION_SERVICE_TYPES,MANAGED_LICENSE,USAGE_CREDITS,CDH_SOFTWARE_COMPONENT_PGI_HISTORY,DATA_VOLUME,DIM_ACTIVE_GATE_OS,ALECKI_CHAR,ALECKI_LONG,BAS_AUDIT_ENTRY,FACT_SERVICE_TECHNOLOGIES,FACT_CLOUD_APPLICATIONS,DIM_USER,WOOPRA_ACTION_PROPERTIES,DIM_EXTENSION_METRIC_GROUP,CDH_MONITORED_VIRTUALIZATION_SERVICE_TYPES,CDH_MOBILE_OS_VERSION_USAGE_HISTORY,DIM_PROBLEM_EVIDENCE_TYPE,TIM_CLONE,SFDC_POC,JIRA_ISSUES,FACT_HOST_TECHNOLOGIES,CDH_FDI_EVENT_HISTORY,CDH_ENVIRONMENTS,TENANT_USAGE_SUMMARY,CDH_SETTING_HISTORY,RR,DIM_HOST_ATTRIBUTES,DIM_SESSION_BROWSER,INTERCOM_CONVERSATIONS,SESSION_REPLAYS_REPORT,FACT_PRODUCT_BEHAVIORAL_EVENTS_AGGR,BI_TEST_1K,RUM_SESSION,DIM_TECHNOLOGY,DIM_PRODUCT_TYPE,ACCOUNT,INTERCOM_CONVERSATION_TAGS,CDH_ALERTING_PROFILE_SEVERITY_RULE_HISTORY,ALECKI_ALL_TYPES,SERVICE,CDH_KUBERNETES_NODE_HISTORY,DIM_CLUSTER,JOBSTATUS,SFDC_ASSIGNMENT,DIM_OPPORTUNITY_TYPE,BILLING_SERVICE_TYPE,FACT_PROCESS_ATTRIBUTES,CDH_PLUGIN_STATE_HISTORY,DIM_SERVICE,CDH_TAG_COVERAGE_ENTITIES_HISTORY,INTERCOM_CONTACTS,FACT_ACTIVE_GATE_MODULES_STATUSES,FACT_COLUMN_USAGE,CDH_DATABASE_INSIGHTS_HISTORY,SFDC_OPPORTUNITY,ISSUE_JIRA_REQUESTS,DIM_CONTRACT,FACT_VERSIONED_MODULES,SFDC_TRIAL,WOOPRA_SESSION,RUM_BEHAVIORAL_EVENTS,DIM_POC_PRODUCT,CDH_SOFTWARE_COMPONENT_DETAILS_PACKAGE_HISTORY,CDH_PREFERENCES_SETTINGS_HISTORY,CDH_SECURITY_PROBLEM_MUTE_STATE_HISTORY,CDH_CLUSTER_EMERGENCY_EMAILS_HISTORY,CDH_INTEGRATION_HISTORY,CDH_SECURITY_PROBLEM_SC_HISTORY,ALECKI_DOUBLE,DIM_CONTRACT_LIMIT_ATTRIBUTES,DIM_SCREEN_RESOLUTION,SERVICE_USAGE_SUMMARY,CDH_TOKEN_STATS_HISTORY,CDH_VERSIONED_MODULE_V2_HISTORY,FACT_ACCOUNT_VERTICALS,FACT_CUSTOMERS,FACT_PROBLEM_EVIDENCE,DIM_TABLE,SYSTEM_PROPERTIES,CDH_SECURITY_PROBLEM_ASSESSMENT_HISTORY,FACT_TRIALS,DIM_DATE,MONITORED_CLOUD_SERVICES_REPORT,CDH_VISITSTORE2_METRICS_HISTORY,CDH_SOFTWARE_COMPONENT_HISTORY,FACT_KUBERNETES_NODES,CDH_HOST_TECH_HISTORY,CDH_SOFTWARE_COMPONENT_DETAILS_VERSION_HISTORY,CDH_TOKEN_STATS_PERMISSION_HISTORY,FACT_POC,CDH_VISIT_STORE_USAGE_HISTORY,SFDC_TASK,FACT_CLOUD_APPLICATION_NAMESPACES,REFERRAL_CODE,DIM_CONTAINER_GROUP_INSTANCE,DAILY_USAGE,FACT_SESSIONS_DAILY_AGGR,CDH_CF_FOUNDATION_HISTORY,TIM2,CDH_HOST_HISTORY,CDH_CUSTOM_CHART_STATS_HISTORY,CDH_ACTIVE_GATE_UPDATE_STATUS_HISTORY,DTU_ACTIVITIES,DAVIS_ACCOUNT_LINK,CDH_AGENT_HISTORY,DIM_DT_ONE,CLOUD_ADOPTION,FACT_AGENTS,BAS_AUDIT_ENTITY,WOOPRA_ACTION,INTERCOM_ADMINS,ENVIRONMENT_USAGE_DAILY_SUMMARY,DIM_TABLE_STATUS,DIM_KUBERNETES_NODE,DIM_CONTAINER_PROVIDER_TYPE,HOST_USAGE_DAILY_SUMMARY,DC_AUDIT_LOG,CDH_CLOUD_NETWORK_INGRESS_HISTORY,CDH_VIRTUALIZATION_SUBSCRIPTION_HISTORY,DIM_AGENT_ENVIRONMENT,CDH_VERSIONED_MODULE_HISTORY,CDH_PLUGIN_HOST_DETAILS_HISTORY,CDH_UEM_CONFIG_TENANT_HISTORY,ENVIRONMENT_USAGE_SUMMARY,FACT_TABLE_GROUP_OWNERS,T,CDH_LOG_MONITORING_ES_STATS_HISTORY,CDH_METRIC_EVENT_CONFIG_ID_FILTER_HISTORY,CDH_PROBLEM_HISTORY,CDH_UEM_CONFIG_METADATA_CAPTURING_SETTINGS_HISTORY,DATASOURCES,DIM_SERVICE_TYPE,DIM_CUSTOMER_TASK,DIM_SESSION_OS,DIM_POWERBI_TABLE,SERVICE_USAGE_DAILY_SUMMARY,DIM_AGENT_TECHNOLOGY_TYPE,MANAGED_LICENSE_QUOTA,CDH_UEM_CONFIG_HISTORY,CDH_API_USAGE_HISTORY,DIM_API_USER_AGENT,TABLE_EXTRACT_INFO,xyz,DIM_APPLICATION,CDH_PROBLEM_EVIDENCE_HISTORY,REF,CDH_CLOUD_APPLICATION_NAMESPACE_HISTORY,CDH_CLOUD_NETWORK_SERVICE_HISTORY,DIM_SESSION_CONTINENT,DIM_CONDITIONAL_PROCEDURE,CDH_RELEASE_HISTORY,LIMITS,PROCESS_STATUS,INFRASTRUCTURE_SOLUTION_ENVIRONMENTS,AUTOPROV_EVENTS,BILLING_ACCOUNT,FACT_TABLE,CDH_CLOUD_APPLICATION_HISTORY,WOOPRA_PAGES,DIM_PROBLEM_SOURCE,ROLE,CDH_BILLING_SYNTHETIC_USAGE_HISTORY,CDH_FDI_EVENT_ENTITY_TYPE_AGGREGATIONS_HISTORY,CDH_PROBLEM_IMPACTED_ENTITIES_HISTORY,CLOUD_USAGE_REPORT,CDH_EXTENDED_TENANT_CONFIG_HISTORY,CDH_API_USER_AGENT_USAGE_HISTORY,DIM_COMPETITOR,DIM_OPPORTUNITY,FACT_PROBLEM_NATURAL_EVENTS,MC_ACCOUNT,FACT_PROBLEM_RANKED_ENTITIES,ALECKI_BOOLEAN,CDH_EXTRACT_STATISTICS,CDH_CONDITIONAL_PROCEDURES_HISTORY,CDH_CLUSTER_CONTACTS_HISTORY,CDH_ENDED_SESSIONS_HISTORY,FACT_CONDITIONAL_PROCEDURE_ENTITY_RULES,CDH_PROBLEM_NATURAL_EVENT_HISTORY,DIM_TABLE_GROUP,SFDC_MANAGED_LICENSE,DIM_CLOUD_APPLICATION_INSTANCE,DIM_CLOUD_APPLICATION,DIM_CONTAINER_GROUP,FACT_CUSTOMER_TASKS,DIM_POC_ACCOUNT,FACT_SESSIONS,DIM_POWERBI_STATE,DIM_HOST_TECHNOLOGY,CDH_CLOUD_NETWORK_POLICY_HISTORY,FACT_PROBLEM_IMPACTED_ENTITIES,CDH_SLO_HISTORY,FACT_PROCESSES,SQL_PERFORMANCE,CDH_DEEP_MONITORING_SETTINGS_V2_HISTORY,DIM_LICENSE,DIM_CURRENCY,PACKAGE,CDH_EXTENSION_HISTORY,UPGRADE_EXECUTION,R2,UNIQUE_HOSTS_TECHNOLOGY_HISTORY,MONTHLY_CONSUMPTION_REPORT,MONTHLY_CONSUMPTION_STAGING,CDH_PROBLEM_CAPPING_INFORMATION_HISTORY,FACT_CONTAINER_GROUPS,DIM_POWERBI_MODEL,PROMO_CODE,BI_TEST_200,ALECKI_FLOAT,REPORT_STATUS,TENANT_SUB_ENVIRONMENT,DIM_PROBLEM_EVENT_TYPE,INTERCOM_USERS,ENVIRONMENT_SERVICE_DAILY_SUMMARY,FACT_API_USAGE,BI_TEST_65K,FACT_COLUMN,DIM_VERTICAL,FACT_OPPORTUNITY_PRODUCTS,CDH_PROBLEM_EVENT_INSTANCE_CLASSES_HISTORY,USERS_AND_QUERIES_COUNT_STATS,CONTRACT_PRICING,EXTENSION_REPOSITORY_INFO,FACT_PRODUCT_BEHAVIORAL_EVENTS,CDH_PROCESS_HISTORY,SYNTHETIC_LOCATIONS,ALECKI_SHORT,WOOPRA_PAGEVIEW_BAS,BILLING_REQUEST,CDH_CLUSTERS,SFDC_DYNATRACE_ACCOUNT,DIM_APPLICATION_TYPE,MANAGED_ACCOUNT,ETL_DAILY_INGESTED_DATA_VOLUME,ALECKI_TIMESTAMP,DAVIS_TENANT,FACT_SERVICES,ENVIRONMENT_SERVICE_SUMMARY,DIM_CLOUD_APPLICATION_INSTANCE_PHASE,FACT_ACTIVE_GATES,CDH_METRIC_EVENT_CONFIG_COUNT_HISTORY,DIM_COLUMN,FACT_DATA_QUALITY_ISSUES,SFDC_OPPORTUNITY_PRODUCT,DIM_PROCESS,FACT_ENVIRONMENT_USAGE,BI_TEST_100,CDH_CONTAINER_MEMORY_LIMIT_HISTORY,FACT_DDU_METRICS,ALECKI_TIMESTAMP_TZ,FACT_COLUMN_DEPENDENCIES", "snowflake.user.privilege.last_altered": 1615479617462000000, "db.user": "PIPELINE", - "dsoa.run.context": "users" + "dsoa.run.context": "users", + "dsoa.run.plugin": "test_users" }, { "content": "users", @@ -82,6 +89,7 @@ "snowflake.user.privilege.grants": "FACT_PROBLEM_IMPACTED_ENTITIES,FACT_OPPORTUNITY_PRODUCTS,DIM_API_ENDPOINT,CDH_PROBLEM_EVENT_METADATA_HISTORY,FACT_AGENT_TECHNOLOGIES,CDH_SOFTWARE_COMPONENT_DETAILS_VERSION_HISTORY,SFDC_TENANT,CDH_CONTAINER_GROUP_HISTORY,CDH_PROBLEM_NATURAL_EVENT_HISTORY,BAS_MANAGED_LICENSE,CDH_COMPETITOR_JS_FRAMEWORK_USAGE_HISTORY,VW_REP_DATE_DIMENSION,DEHASH_TENANT,CDH_TOKEN_STATS_HISTORY,CDH_CONDITIONAL_PROCEDURES_HISTORY,V_KEY_USER_ACTION,FACT_APPLICATIONS,CDH_PROBLEM_CAPPING_INFORMATION_HISTORY,CDH_PROBLEM_IMPACTED_ENTITIES_HISTORY,DIM_VERTICAL,BAS_PROMO_USAGE,INTERCOM_CONTACTS,CDH_CLOUD_APPLICATION_NAMESPACE_HISTORY,CDH_API_USER_AGENT_USAGE_HISTORY,DIM_CLOUD_APPLICATION_INSTANCE,FACT_PROBLEMS,FACT_POC,FACT_ACTIVE_GATES,AUTOPROV_EVENTS,CDH_DISCOVERED_VIRTUALIZATION_SERVICE_TYPES,CDH_DASHBOARD_CONFIG_HISTORY,CDH_LOG_MONITORING_STATS_HISTORY,CDH_JS_FRAMEWORK_USAGE_HISTORY,V_LOG_EVENTS,DIM_PROBLEM_EVENT_STATUS,RUM_BEHAVIORAL_EVENT_PROPERTIES,DIM_POC,CDH_SESSION_STORAGE_USAGE_HISTORY,DIM_DT_ONE,DIM_SERVICE_TYPE,CDH_SECURITY_PROBLEM_ASSESSMENT_HISTORY,DIM_CF_FOUNDATION,BAS_TENANT_SUB_ENVIRONMENT,RUM_SESSION,CDH_ALERTING_PROFILE_SEVERITY_RULE_HISTORY,FACT_API_USAGE,JIRA_ISSUES,FACT_ENVIRONMENT_UNITS_CONSUMPTION,BAS_ENVIRONMENT_SERVICE_SUMMARY,CDH_ODIN_AGENT_HISTORY,DIM_PROBLEM_EVENT_TYPE,DIM_SESSION_OS,BAS_COMPANY,FACT_DDU_METRICS,BAS_SFDC_TRIAL,BAS_ROLE,V_CLOUD_AUTOMATION_SOLUTION,CDH_INTERNAL_ENTITY_MODEL_CAPPING_INFORMATION_HISTORY,DIM_HOST_ATTRIBUTES,CDH_FDI_EVENT_HISTORY,CDH_METRIC_EVENT_CONFIG_THRESHOLD_BASED_MODEL_HISTORY,CDH_SETTING_HISTORY,DIM_PROCESS,DIM_POC_PRODUCT,DIM_APPLICATION,DIM_TECHNOLOGY,DIM_PRODUCT_BEHAVIORAL_EVENT,BAS_BILLING_PROVIDER,CDH_TILE_FILTER_CONFIG_HISTORY,CDH_CLOUD_NETWORK_SERVICE_HISTORY,BAS_USER,BAS_TIME_ZONE,BAS_AUDIT_ENTITY,CDH_SYNTHETIC_MONITOR_LOCATION_HISTORY,BAS_CONTRACT,CDH_REQUEST_ATTRIBUTE_STATS_HISTORY,MONTHLY_CONSUMPTION_EXT,DIM_SALES_REGION,CDH_METRIC_EVENT_CONFIG_NAME_FILTER_HISTORY,BAS_ACCOUNT_STATUS,V_APPS_AND_MICROSERVICES_OPENT,CDH_ACTIVE_GATE_UPDATE_STATUS_HISTORY,CDH_UEM_CONFIG_HISTORY,CONTRACT_CONSUMPTION_LATEST,WOOPRA_ACTION,CDH_SECURITY_PROBLEM_HISTORY,DAVIS_USER,DIM_ACTIVE_GATE_MODULE,DAVIS_TENANT,INTERCOM_USERS,CDH_ENVIRONMENTS,CDH_SYNTHETIC_MONITOR_HISTORY,DIM_ENVIRONMENT,RUM_PAGEVIEW,DIM_EXTENSION_METRIC_GROUP,CDH_TOKEN_STATS_PERMISSION_HISTORY,CDH_CUSTOM_SESSIONS_APPLICATION_TECHNOLOGY_TYPE_HISTORY,DIM_SERVICE,DIM_SESSION_CITY,V_RUM_PROPERTIES,V_DEM_CUSTOM_APPLICATION_SESSION,CDH_VIRTUALIZATION_SUBSCRIPTION_HISTORY,V_COVID_19_CONSUMPTION,CDH_CLOUD_APPLICATION_HISTORY,CDH_SOFTWARE_COMPONENT_PGI_HISTORY,INTERCOM_CONVERSATION_PARTS,CDH_CLOUD_NETWORK_INGRESS_HISTORY,CDH_TAG_COVERAGE_HISTORY,WOOPRA_PAGEVIEW,CDH_FDI_EVENT_METADATA_HISTORY,V_COLUMN_USAGE_LOG,WOOPRA_PAGEVIEW_BAS,CDH_FDI_EVENT_ENTITY_TYPE_AGGREGATIONS_HISTORY,DIM_SESSION_CONTINENT,TYPES_V,DIM_HOST_TECHNOLOGY,CDH_CLUSTERS,BAS_BILLING_SERVICE_TYPE,FACT_HOSTS_AGG_MONTH,CDH_FDI_EVENT_TYPE_AGGREGATIONS_HISTORY,DIM_VERBATIM_TYPE,CDH_METRIC_EVENT_CONFIG_HISTORY,CDH_FEATURE_FLAG_HISTORY,DAILY_USAGE,BAS_AUDIT_ENTRY,CDH_CLUSTER_TAGS_HISTORY,DIM_LICENSE,BAS_BILLING_USAGE,CDH_ACTIVE_GATE_MODULES_STATUSES_HISTORY,CDH_ACTIVE_GATE_HISTORY,CDH_PROBLEM_RANKED_ENTITY_HISTORY,CDH_METRIC_EVENT_CONFIG_COUNT_HISTORY,SFDC_OPPORTUNITY,CDH_HOST_TECH_HISTORY,DIM_CONTAINER_GROUP_INSTANCE,CDH_INTEGRATION_HISTORY,EXTENSION_REPOSITORY_INFO,VW_REP_SNOWFLAKE_STORAGE_USAGE_MONTHLY_SUMMARY,CDH_VIRTUALIZATION_HISTORY,CDH_BILLING_SYNTHETIC_USAGE_HISTORY,FACT_CF_FOUNDATIONS,CDH_CLUSTER_HISTORY,DIM_DT_ACCOUNT,DIM_USAGE_TYPE,DIM_OPPORTUNITY,CDH_CUSTOM_CHART_STATS_HISTORY,DIM_CURRENCY,INTERCOM_CONVERSATIONS,DIM_CLUSTER,CDH_MONITORED_VIRTUALIZATION_SERVICE_TYPES,DIM_CONTAINERIZATION_TYPE,V_DEM_STAR_RATING,DIM_DEVICE_TYPE,CDH_CUSTOM_SESSIONS_APPLICATION_TECHNOLOGY_BILLING_TYPE_HISTORY,DIM_OPPORTUNITY_TYPE,FACT_TRIALS,CDH_TENANT_NETWORK_ZONE_STATS_HISTORY,CDH_CLOUD_APPLICATION_INSTANCE_HISTORY,DIM_SCREEN_RESOLUTION,BAS_TENANT,DAVIS_CHANNEL_CONFIGURATION,RUM_BEHAVIORAL_EVENTS,CDH_FDI_EVENT_INSTANCE_CLASSES_HISTORY,DIM_METRIC,DIM_COMPETITOR,FACT_PROBLEM_EVIDENCE,DIM_CLOUD_APPLICATION_NAMESPACE,DIM_PRODUCT_PAGE,CDH_SECURITY_PROBLEM_MUTE_STATE_HISTORY,DIM_PROCESS_GROUP,CDH_APPLICATION_HISTORY,CDH_PLUGIN_HOST_DETAILS_HISTORY,CDH_MAINFRAME_MSU_HISTORY,DIM_TRIAL,CDH_CLUSTER_CONTACTS_HISTORY,V_ABUSIVE_TRIALS,FACT_API_USER_AGENT_USAGE,DIM_API_USER_AGENT,BAS_ACCOUNT,DEHASH_CLUSTER,DIM_APPLICATION_TYPE,BAS_ENVIRONMENT_USAGE_SUMMARY,SFDC_TASK,CDH_CONTAINER_GROUP_INSTANCE_HISTORY,FACT_PROCESS_TECHNOLOGIES,CDH_PLUGIN_STATE_HISTORY,BAS_TENANT_USAGE_SUMMARY,FACT_SERVICES,A,CDH_METRIC_QUERY_STATS_HISTORY,CDH_CF_FOUNDATION_HISTORY,BAS_TENANT_USAGE,CDH_CF_FOUNDATION_HOST_HISTORY,REFERRAL_CODE,DIM_KUBERNETES_NODE,CDH_SECURITY_PROBLEM_SC_HISTORY,UNIQUE_HOSTS_TECHNOLOGY_HISTORY_NEW,DIM_VERSIONED_MODULE,CDH_ALERTING_PROFILE_HISTORY,CDH_TOTAL_FDI_EVENT_COUNT_HISTORY,MC_MANAGED_LICENSE_QUOTA,SFDC_OPPORTUNITY_PRODUCT,DIM_CONTRACT_LIMIT_ATTRIBUTES,FACT_AGENTS,DIM_CUSTOMER,FACT_CONTAINER_GROUP_INSTANCES,DIM_DATE,BAS_TENANT_LICENSE,SFDC_PROJECT,CONTRACT_CONSUMPTION,CDH_UEM_CONFIG_PROPERTY_TAG_HISTORY,BAS_TENANT_USAGE_DAILY_SUMMARY_VIEW,BAS_TENANT_STATUS,V_DEM_GOALS,CDH_MOBILE_OS_VERSION_USAGE_HISTORY,DIM_HOST_ATTRIBUTES_HISTORY,BAS_EMPLOYEE_COUNT,CDH_SOFTWARE_COMPONENT_DETAILS_HISTORY,FACT_CUSTOMER_ACCOUNTS,DIM_PROBLEM_EVIDENCE_TYPE,CDH_EXTENSION_HISTORY,FACT_CONTAINER_GROUPS,DIM_CLOUD_APPLICATION_INSTANCE_PHASE,FACT_CUSTOMER_TASKS,DIM_AGENT,CUSTOMER_ACCOUNT_MAPPING,CDH_SOFTWARE_COMPONENT_DETAILS_PACKAGE_HISTORY,DIM_PROBLEM,CDH_CLUSTER_EMERGENCY_EMAILS_HISTORY,CDH_PROCESS_HISTORY,PAYING_ACCOUNTS_MONTHLY,CDH_VISITSTORE2_METRICS_HISTORY,CDH_PREFERENCES_SETTINGS_HISTORY,X,FACT_CONTRACT_LATEST_USAGE,CDH_RELEASE_HISTORY,CDH_TAG_COVERAGE_ENTITIES_HISTORY,V_APPS_AND_MICROSERVICES_SERVERLESS_USAGE,CDH_DEEP_MONITORING_SETTINGS_FEATURE_V2_HISTORY,CDH_PROBLEM_EVIDENCE_HISTORY,BAS_TENANT_LAST_ACCESS_DATE,FACT_SESSIONS,FACT_CUSTOMERS,CDH_CONTAINER_MEMORY_LIMIT_HISTORY,DIM_SESSION_BROWSER,INTERCOM_CONVERSATION_TAGS,DIM_ENVIRONMENT_ATTRIBUTES,V_CLOUD_USAGE_REPORT,BAS_MONTHLY_USAGE,DIM_AREA,BAS_MANAGED_LICENSE_QUOTA,MONITORED_CLOUD_SERVICES_REPORT,VW_REP_SNOWFLAKE_WAREHOUSE_METERING_HISTORY,CDH_AGENT_HISTORY,FACT_HOSTS_AGG,DIM_GEOGRAPHY,DISCOVERED_CLOUD_SERVICES_REPORT,FACT_CONTRACT_USAGE,DIM_ACTIVE_GATE_OS,CDH_DEEP_MONITORING_SETTINGS_V2_HISTORY,DIM_COUNTRY,BAS_MANAGED_CLUSTER,FACT_HOSTS,BAS_MANAGED_ACCOUNT,VW_REP_SNOWFLAKE_PIPE_USAGE_HISTORY,V_CLOUD_INTEGRATION_USAGE,CDH_CONTAINER_MEMORY_USAGE_HISTORY,CDH_DDU_TRACES_BY_ENTITY_HISTORY,FACT_HOST_TECHNOLOGIES,DIM_ACTIVE_GATE,DIM_CONTAINER_PROVIDER_TYPE,DTU_ACTIVITIES,CDH_DEEP_MONITORING_SETTINGS_HISTORY,BAS_SERVICE_USAGE_DAILY_SUMMARY,SYNTHETIC_LOCATIONS,CDH_SOFTWARE_COMPONENT_DETAILS_EVIDENCE_HISTORY,CDH_ENVIRONMENT_RAW,CDH_EXTENDED_TENANT_CONFIG_HISTORY,BAS_LIMITS,CDH_CLOUD_NETWORK_POLICY_HISTORY,BAS_PACKAGE,FACT_ENTITY_TAG_COVERAGE,FACT_CLOUD_APPLICATION_INSTANCES,V_CONVERSION_GOALS,FACT_PROCESSES,DIM_POC_ACCOUNT,DIM_AGENT_TECHNOLOGY_TYPE,FACT_ACCOUNT_VERTICALS,DIM_CLUSTER_ATTRIBUTES,PARTNER_REFERRAL,BAS_ENVIRONMENT_SERVICE_DAILY_SUMMARY,CDH_UEM_CONFIG_METADATA_CAPTURING_SETTINGS_HISTORY,INTERCOM_ADMINS,DIM_DEM_GOALS,CDH_ENDED_SESSIONS_HISTORY,DIM_EXTENSION,FACT_CLOUD_APPLICATION_NAMESPACES,CDH_BILLING_APP_SESSIONS_HISTORY,FACT_KUBERNETES_NODES,DEHASH_ACCOUNT,INFRASTRUCTURE_SOLUTION_ACCOUNTS,CDH_DDU_METRICS_BY_METRIC_HISTORY,DIM_PROBLEM_SOURCE,DIM_HOST,DIM_KUBERNETES_CLUSTER,DIM_ACTIVE_GATE_TYPE,INFRASTRUCTURE_SOLUTION_ENVIRONMENTS_NEW,SFDC_ACCOUNT,DIM_CUSTOMER_TASK,FACT_VERSIONED_MODULES,CDH_ENVIRONMENT,DIM_AGENT_ATTRIBUTES,BAS_BILLING_REQUEST,DIM_CONDITIONAL_PROCEDURE,MC_ACCOUNT,V_INFRASTRUCTURE_SOLUTION,CDH_SOFTWARE_COMPONENT_HISTORY,CDH_SLO_HISTORY,CLOUD_USAGE_REPORT,V_DT_VALUE_METRICS,CDH_VISIT_STORE_USAGE_HISTORY,CDH_ODIN_AGENT_ME_IDENTIFIER_HISTORY,FACT_PROBLEM_NATURAL_EVENTS,BAS_AUDIT_FIELD,DIM_UNIQUE_ENVIRONMENTS,AUTOPROV_EVENTS_FEATURES,CDH_MOBILE_AGENT_VERSION_USAGE_HISTORY,BAS_REGION,WOOPRA_SESSION,CDH_VULNERABILITY_MATCHING_METADATA_HISTORY,BAS_SERVICE_USAGE_SUMMARY,INFRASTRUCTURE_SOLUTION_ACCOUNTS_NEW,WOOPRA_ACTION_PROPERTIES,FACT_CLOUD_APPLICATIONS,DIM_SESSION_REGION,CDH_VERSIONED_MODULE_V2_HISTORY,CDH_SERVICE_HISTORY,INTERCOM_COMPANIES,DIM_DT_ACCOUNT_ATTRIBUTES,SESSION_REPLAYS_REPORT,FACT_ENVIRONMENT_USAGE,BAS_USAGE_CREDITS,DIM_DT_ACCOUNT_CURRENT_ATTRIBUTES,V_UNIQUE_HOST_TECHNOLOGIES,SFDC_MANAGED_LICENSE,CDH_CLUSTER_NETWORK_ZONE_STATS_HISTORY,CDH_API_USAGE_HISTORY,DAVIS_USAGE,CDH_CONDITIONAL_PROCEDURES_RULES_HISTORY,FACT_OPPORTUNITIES,BAS_ENVIRONMENT_USAGE_DAILY_SUMMARY_VIEW,BAS_SERVICE,CDH_PROBLEM_HISTORY,SFDC_DYNATRACE_ACCOUNT,FACT_ACTIVE_GATE_UPDATE_STATUS,FACT_ACTIVE_GATE_MODULES_STATUSES,BAS_CONTRACT_PRICING,CDH_PROBLEM_EVENT_INSTANCE_CLASSES_HISTORY,V_ACCOUNT_STAR_RATING,CDH_DATABASE_INSIGHTS_ENDPOINT_DETAILS_HISTORY,DIM_PRODUCT_TYPE,FACT_PROCESS_ATTRIBUTES,MONTHLY_CONSUMPTION_STAGING,FACT_CUSTOMER_SUPPORT,BAS_TENANT_USAGE_DAILY_SUMMARY,DIM_CLOUD_APPLICATION,FACT_PRODUCT_BEHAVIORAL_EVENTS,DIM_PRODUCT,DIM_VERSION,CDH_METRIC_EVENT_CONFIG_ID_FILTER_HISTORY,BAS_PROMO_CODE,CDH_PROBLEM_ROOT_CAUSE_GROUP_HISTORY,SFDC_POC,DIM_CONTAINER_GROUP,DAVIS_ACCOUNT_LINK,CDH_UEM_CONFIG_TENANT_HISTORY,DIM_CONTRACT,CDH_PROBLEM_EVIDENCE_HISTORY_ARCHIVE,CLOUD_ADOPTION,INFRASTRUCTURE_SOLUTION_ENVIRONMENTS,BAS_CONTRACT_BILLING_INFO,DIM_PRODUCT_USER,SFDC_ASSIGNMENT,DIM_OPPORTUNITY_STAGE,UNIQUE_HOSTS_TECHNOLOGY_HISTORY,FACT_SERVICE_TECHNOLOGIES,MONTHLY_CONSUMPTION_REPORT,CDH_DASHBOARD_CONFIG_TILE_HISTORY,DIM_CLOUD_APPLICATION_TYPE,B,CDH_KUBERNETES_NODE_HISTORY,FACT_TAG_COVERAGE,FACT_PRODUCT_PAGE_VIEWS,FACT_CONDITIONAL_PROCEDURE_ENTITY_RULES,CDH_LOG_MONITORING_ES_STATS_HISTORY,CDH_PLUGIN_METRIC_STATS_HISTORY,BAS_ENVIRONMENT_USAGE_DAILY_SUMMARY,CDH_HOST_HISTORY,CDH_VERSIONED_MODULE_HISTORY,BAS_BILLING_ACCOUNT,FACT_PROBLEM_RANKED_ENTITIES,DIM_CLOUD_APPLICATION_INSTANCE_TYPE,CDH_DEEP_MONITORING_SETTINGS_FEATURES_HISTORY,BAS_HOST_USAGE_DAILY_SUMMARY,CDH_LOG_MONITORING_METRIC_STATS_HISTORY,DIM_REGION,CDH_DATABASE_INSIGHTS_HISTORY,CDH_MOBILE_CRASHES_BY_RETRIEVAL_DELAY_HISTORY,WOOPRA_PAGES,CDH_DDU_TRACES_BY_DESCRIPTION_HISTORY", "snowflake.user.privilege.last_altered": 1615219846703000000, "db.user": "ANDRZEJLECKI", - "dsoa.run.context": "users" + "dsoa.run.context": "users", + "dsoa.run.plugin": "test_users" } -] \ No newline at end of file +] diff --git a/test/test_results/test_warehouse_usage/biz_events.json b/test/test_results/test_warehouse_usage/biz_events.json index 3c8c762f..15ca00f6 100644 --- a/test/test_results/test_warehouse_usage/biz_events.json +++ b/test/test_results/test_warehouse_usage/biz_events.json @@ -7,14 +7,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_warehouse_usage", "dsoa.task.exec.status": "STARTED", - "app.bundle": "self-monitoring", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring", + "dsoa.run.plugin": "test_warehouse_usage" } }, { @@ -25,14 +26,15 @@ "event.provider": "test.dsoa2025.snowflakecomputing.com", "dsoa.task.name": "test_warehouse_usage", "dsoa.task.exec.status": "FINISHED", - "app.bundle": "self-monitoring", + "dsoa.run.plugin": "test_warehouse_usage", + "app.bundle": "self_monitoring", "app.id": "dynatrace.snowagent", "db.system": "snowflake", "service.name": "test.dsoa2025", "deployment.environment": "TEST", "host.name": "test.dsoa2025.snowflakecomputing.com", "telemetry.exporter.name": "dynatrace.snowagent", - "dsoa.run.context": "self-monitoring" + "dsoa.run.context": "self_monitoring" } } -] +] \ No newline at end of file