def test_correlation_identifiers_without_trace(self): # ensures `None` is returned if no Traces are active with override_global_tracer(self.tracer): trace_id, span_id = helpers.get_correlation_ids() ok_(trace_id is None) ok_(span_id is None)
def test_correlation_identifiers_without_trace(self): # ensures `None` is returned if no Traces are active with override_global_tracer(self.tracer): trace_id, span_id = helpers.get_correlation_ids() self.assertIsNone(trace_id) self.assertIsNone(span_id)
def test_correlation_identifiers_missing_context(self): # ensures we return `None` if there is no current context self.tracer.get_call_context = mock.MagicMock(return_value=None) with override_global_tracer(self.tracer): trace_id, span_id = helpers.get_correlation_ids() self.assertIsNone(trace_id) self.assertIsNone(span_id)
def test_correlation_identifiers_with_disabled_trace(self): # ensures `None` is returned if tracer is disabled with override_global_tracer(self.tracer): self.tracer.enabled = False self.tracer.trace('MockSpan') trace_id, span_id = helpers.get_correlation_ids() self.assertIsNone(trace_id) self.assertIsNone(span_id)
def test_correlation_identifiers(self): # ensures the right correlation identifiers are # returned when a Trace is active with override_global_tracer(self.tracer): span = self.tracer.trace('MockSpan') active_trace_id, active_span_id = span.trace_id, span.span_id trace_id, span_id = helpers.get_correlation_ids() self.assertEqual(trace_id, active_trace_id) self.assertEqual(span_id, active_span_id)
def test_correlation_identifiers(self): # ensures the right correlation identifiers are # returned when a Trace is active with override_global_tracer(self.tracer): span = self.tracer.trace('MockSpan') active_trace_id, active_span_id = span.trace_id, span.span_id trace_id, span_id = helpers.get_correlation_ids() eq_(trace_id, active_trace_id) eq_(span_id, active_span_id)
def tracer_injection(logger, log_method, event_dict): # get correlation ids from current tracer context trace_id, span_id = get_correlation_ids() # Add ids to Structlog event dictionary event_dict["dd.trace_id"] = trace_id or 0 event_dict["dd.span_id"] = span_id or 0 # add the env, service, and version configured for the tracer event_dict["dd.env"] = ddtrace.config.env or "" event_dict["dd.service"] = ddtrace.config.service or "" event_dict["dd.version"] = ddtrace.config.version or "" return event_dict
def datadog_tracer_injection(_, __, event_dict): """Propagate trace ids for Datadog.""" if get_correlation_ids is None: # Do nothing if ddtrace module is not available. return event_dict # Hack to prevent infinite loop in asyncio event loop creation in debug log-level # https://github.com/DataDog/dd-trace-py/issues/1003 if event_dict["level"] == "debug" and event_dict.get( "logger") == "asyncio": return event_dict trace_id, span_id = get_correlation_ids() if trace_id and span_id: event_dict["dd.trace_id"] = trace_id event_dict["dd.span_id"] = span_id return event_dict
def func(): logger.info('Hello!') return get_correlation_ids()
def func(): logger.info('Hello!') return get_correlation_ids(tracer=self.tracer)
def json_record(self, message: str, record: LogRecord): """Convert the record to JSON and inject Datadog attributes.""" record_dict = dict(record.__dict__) record_dict["message"] = message record_dict["tm.logger.library"] = "muselog" if "timestamp" not in record_dict: # UNIX time in milliseconds record_dict["timestamp"] = int(record.created * 1000) if "severity" not in record_dict: record_dict["severity"] = record.levelname # Source Code if "logger.name" not in record_dict: record_dict["logger.name"] = record.name if "logger.method_name" not in record_dict: record_dict["logger.method_name"] = record.funcName if "logger.thread_name" not in record_dict: record_dict["logger.thread_name"] = record.threadName # NOTE: We do not inject 'host', 'source', or 'service', as we want # Datadog agent and docker labels to handle that for the time being. # This may change. exc_info = record.exc_info try: if self.trace_enabled: # get correlation ids from current tracer context trace_id, span_id = helpers.get_correlation_ids() record_dict["dd.trace_id"] = trace_id or 0 record_dict["dd.span_id"] = span_id or 0 if "context" in record_dict: context_obj = dict() context_value = record_dict.get("context") array = context_value.replace(" ", "").split(",") for item in array: key, val = item.split("=") # del key from record before replacing with modified version # NOTE: This is hacky. Need to provide a general purpose # context-aware logger. if key in record_dict: del record_dict[key] key = f"ctx.{key}" context_obj[key] = int(val) if val.isdigit() else val record_dict.update(context_obj) del record_dict["context"] except Exception: exc_info = sys.exc_info() # Handle exceptions, including those in our formatter if exc_info: # QUESTION: If exc_info was set by us, do we alter the log level? # Probably not, as a formatter should never be altering the record # directly. # I think that instead we should avoid code that can conveivably # raise exceptions in our formatter. That is not possible until we update # the context handling code and we can ensure helpers.get_correlation_ids() # will not raise any exceptions. if "error.kind" not in record_dict: record_dict["error.kind"] = exc_info[0].__name__ if "error.message" not in record_dict: record_dict["error.message"] = str(exc_info[1]) if "error.stack" not in record_dict: limit = int(os.environ.get("DATADOG_ERROR_STACK_LIMIT", 10000)) record_dict["error.stack"] = self.formatException( exc_info)[0:limit] return record_dict
def test_set_correlation_ids(self): set_correlation_ids() trace_id, span_id = get_correlation_ids() self.assertEqual(trace_id, "123") self.assertEqual(span_id, "456")
def test_set_correlation_ids(self): set_correlation_ids() trace_id, span_id = get_correlation_ids() self.assertEqual(trace_id, '123') self.assertEqual(span_id, '456')