cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Custom Python Extension 2.0 does not report metrics correctly to the platform

MarianneR
Frequent Guest

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):

MarianneR_0-1718998619532.png

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!

2 REPLIES 2

Julius_Loman
DynaMight Legend
DynaMight Legend

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. 😪

Certified Dynatrace Master | Alanata a.s., Slovakia, Dynatrace Master Partner

Thank you so much for the answer, I'll remove the dimension!

Featured Posts