21 Jun 2024 09:53 PM - last edited on 24 Jun 2024 08:04 AM by MaciejNeumann
I have developed a Python extension using the 2.0 framework that connects to a Microsoft SQL Server, executes a stored procedure, and reports custom metrics to Dynatrace. The metrics appear on the platform, but absolutely no data shows up (for any given timeframe):
Data should be present, since the extension has an enebled configuration and its staus has been at "OK" for several days now.
When I look at the OneAgent diagnostics, I don't see any errors and in the python.exe.log file I see the following written at every minute (after the query() method has ended):
[...config_id...][python-...][out]2024-06-20 15:49:01,743 [INFO] api (ThreadPoolExecutor-1_0): Sent 55 metric lines to EEC: [MintResponse(lines_ok=55, lines_invalid=0, error=None, warnings=None)]
With the other debugging logs I have written for myself, I see that the connection is being made with the mssql server and that the data is being correctly extracted. From the above log, it seems as though Dynatrace should be receiving the metrics I have sent.
In my extension code in the query(self) method, I have the following code:
connection_jobs = pymssql.connect(server, user, password, database, as_dict = True)
connection_steps = pymssql.connect(server, user, password, database, as_dict = True)
try:
# Call stored proc sp_help_job @enabled = 1
cursor_jobs = connection_jobs.cursor()
cursor_jobs.callproc('sp_help_job', (None, None, None, None, None, None, None, 1, None, None, None, None, None))
for job in cursor_jobs:
dimensions_job = {'job_id': str(job['job_id']),
'dt.entity.hostname': job['originating_server'],
'name': job['name'],
'type': int(job['type']),
'owner': job['owner'],
'category': job['category'],
'current_execution_status': int(job['current_execution_status']),
'has_step': job['has_step'],
'step_id': int(job['current_execution_step'][0]),
'current_execution_step': job['current_execution_step'][3:-1],
}
self.logger.info(dimensions_job)
# Report job metric
self.report_metric("mssql.job.status", job['last_run_outcome'], dimensions_job)
# if the job never ran, job['last_run_outcome'] == 5
if job['last_run_outcome'] == 0:
self.report_dt_event(event_type = "ERROR_EVENT",
title = "job failed",
start_time = job["last_run_time"],
entity_selector = f"entityID(\"{dimensions_job['job_id']}\")")
cursor_steps = connection_steps.cursor()
# Call stored proc sp_help_jobstep @job_id = dimensions_job['job_id']
cursor_steps.callproc('sp_help_jobstep', (dimensions_job['job_id'], None, None, None, None))
for step in cursor_steps:
dimensions_step = {'job_id': dimensions_job['job_id'],
'job_name': dimensions_job['name'],
'step_name': step['step_name'],
'step_id': step['step_id'],
'dt.entity.hostname': job['originating_server']
}
self.logger.info(dimensions_step)
# Report step metric
self.report_metric("mssql.jobstep.status", step['last_run_outcome'], dimensions_step)
if step['last_run_outcome'] == 0 and step['last_run_date'] != 0:
self.report_dt_event(event_type = "ERROR_EVENT",
title = "job step failed",
start_time = step["last_run_time"],
entity_selector = f"entityID(\"{dimensions_step['job_name']}_{dimensions_step['step_id']}\")")
cursor_steps.close()
cursor_jobs.close()
except Exception as e:
self.logger.info('Exception:', e)
finally:
connection_jobs.close()
connection_steps.close()
As you can see in the code, I use the report_metric method to report metrics.
In the extension.yaml file, I have the following:
name: custom:foo-extension
version: 0.0.14
minDynatraceVersion: "1.253"
author:
name: "Name"
python:
runtime:
module: foo_extension
version:
min: "3.9"
activation:
remote:
path: activationSchema.json
local:
path: activationSchema.json
featureSets:
- featureSet: Job
metrics:
- key: mssql.job.status
- featureSet: Job Step
metrics:
- key: mssql.jobstep.status
metrics:
- key: mssql.job.status
metadata:
description: last run outcome of the job
displayName: mssql job status
unit: gauge
dimensions:
- key: job_id
displayName: Job ID
- key: name
displayName: Job Name
- key: dt.entity.hostname
displayName: Originating Server
- key: category
displayName: Category
- key: type
displayName: Type
- key: owner
displayName: Owner
- key: current_execution_status
displayName: Current Execution Status
- key: has_step
displayName: Total Number of Steps Per Job
- key: current_execution_step
displayName: Current Execution Step's Name
- key: step_id
displayName: This Step's ID
- key: mssql.jobstep.status
metadata:
description: last run outcome of the job step
displayName: mssql job step status
unit: gauge
dimensions:
- key: job_id
displayName: This Job's ID
- key: job_name
displayName: This Job's Name
- key: step_id
displayName: This Step's ID
- key: step_name
displayName: Step Name
- key: dt.entity.hostname
displayName: originating server
Could this problem have any thing to do with the dt.entity.hostname that I have specified; for example, if this name doesn't match exactly with the entity name in Dynatrace?
What are the other possible causes for this missing data? What elements should I look into to find it? Are there places I have missed where I could find information on errors with the execution of my extension?
Any help on the matter is greatly appreciated. Thank you!
Solved! Go to Solution.
21 Jun 2024 10:18 PM
Yes, that's the reason. The dt.entity.* dimensions are reserved for Dynatrace as described here in the metric line protocol description. Unfortunately, Dynatrace drops such metrics at the moment without any error. 😪
24 Jun 2024 04:05 PM
Thank you so much for the answer, I'll remove the dimension!