def structlog_processor(logger, method_name, event_dict): """ Add three new entries to the event_dict for any processed events: * transaction.id * trace.id * span.id Only adds non-None IDs. :param logger: Unused (logger instance in structlog) :param method_name: Unused (wrapped method_name) :param event_dict: Event dictionary for the event we're processing :return: `event_dict`, with three new entries. """ transaction = execution_context.get_transaction() if transaction: event_dict["transaction.id"] = transaction.id event_dict["service.name"] = transaction.tracer.config.service_name if transaction and transaction.trace_parent: event_dict["trace.id"] = transaction.trace_parent.trace_id span = execution_context.get_span() if span and span.id: event_dict["span.id"] = span.id return event_dict
def _add_attributes_to_log_record(record): """ Add custom attributes for APM tracing fields to a LogRecord object :param record: LogRecord object :return: Updated LogRecord object with new APM tracing fields """ transaction = execution_context.get_transaction() transaction_id = transaction.id if transaction else None record.elasticapm_transaction_id = transaction_id trace_id = transaction.trace_parent.trace_id if transaction and transaction.trace_parent else None record.elasticapm_trace_id = trace_id span = execution_context.get_span() span_id = span.id if span else None record.elasticapm_span_id = span_id record.elasticapm_labels = { "transaction.id": transaction_id, "trace.id": trace_id, "span.id": span_id } return record
def _add_attributes_to_log_record(record): """ Add custom attributes for APM tracing fields to a LogRecord object :param record: LogRecord object :return: Updated LogRecord object with new APM tracing fields """ transaction = execution_context.get_transaction() transaction_id = transaction.id if transaction else None record.elasticapm_transaction_id = transaction_id trace_id = transaction.trace_parent.trace_id if transaction and transaction.trace_parent else None record.elasticapm_trace_id = trace_id span = execution_context.get_span() span_id = span.id if span else None record.elasticapm_span_id = span_id client = get_client() service_name = client.config.service_name if client else None record.elasticapm_service_name = service_name event_dataset = f"{client.config.service_name}.log" if client else None record.elasticapm_event_dataset = event_dataset record.elasticapm_labels = { "transaction.id": transaction_id, "trace.id": trace_id, "span.id": span_id, "service.name": service_name, "event.dataset": event_dataset, } return record
async def call(self, module, method, wrapped, instance, args, kwargs): span = execution_context.get_span() self._update_context_by_request_data(span.context, instance, args, kwargs) status_code, headers, raw_data = await wrapped(*args, **kwargs) span.context["http"] = {"status_code": status_code} return status_code, headers, raw_data
def _build_msg_for_logging( self, event_type, date=None, context=None, custom=None, stack=None, handled=True, **kwargs ): """ Captures, processes and serializes an event into a dict object """ transaction = execution_context.get_transaction() span = execution_context.get_span() if transaction: transaction_context = deepcopy(transaction.context) else: transaction_context = {} event_data = {} if custom is None: custom = {} if date is not None: warnings.warn( "The date argument is no longer evaluated and will be removed in a future release", DeprecationWarning ) date = time.time() if stack is None: stack = self.config.auto_log_stacks if context: transaction_context.update(context) context = transaction_context else: context = transaction_context event_data["context"] = context if transaction and transaction.labels: context["tags"] = deepcopy(transaction.labels) # if '.' not in event_type: # Assume it's a builtin event_type = "elasticapm.events.%s" % event_type handler = self.get_handler(event_type) result = handler.capture(self, **kwargs) if self._filter_exception_type(result): return # data (explicit) culprit takes over auto event detection culprit = result.pop("culprit", None) if custom.get("culprit"): culprit = custom.pop("culprit") for k, v in compat.iteritems(result): if k not in event_data: event_data[k] = v log = event_data.get("log", {}) if stack and "stacktrace" not in log: if stack is True: frames = stacks.iter_stack_frames(skip=3, config=self.config) else: frames = stack frames = stacks.get_stack_info( frames, with_locals=self.config.collect_local_variables in ("errors", "all"), library_frame_context_lines=self.config.source_lines_error_library_frames, in_app_frame_context_lines=self.config.source_lines_error_app_frames, include_paths_re=self.include_paths_re, exclude_paths_re=self.exclude_paths_re, locals_processor_func=lambda local_var: varmap( lambda k, v: shorten( v, list_length=self.config.local_var_list_max_length, string_length=self.config.local_var_max_length, dict_length=self.config.local_var_dict_max_length, ), local_var, ), ) log["stacktrace"] = frames if "stacktrace" in log and not culprit: culprit = stacks.get_culprit(log["stacktrace"], self.config.include_paths, self.config.exclude_paths) if "level" in log and isinstance(log["level"], compat.integer_types): log["level"] = logging.getLevelName(log["level"]).lower() if log: event_data["log"] = log if culprit: event_data["culprit"] = culprit if "custom" in context: context["custom"].update(custom) else: context["custom"] = custom # Make sure all data is coerced event_data = transform(event_data) if "exception" in event_data: event_data["exception"]["handled"] = bool(handled) event_data["timestamp"] = int(date * 1000000) if transaction: if transaction.trace_parent: event_data["trace_id"] = transaction.trace_parent.trace_id # parent id might already be set in the handler event_data.setdefault("parent_id", span.id if span else transaction.id) event_data["transaction_id"] = transaction.id event_data["transaction"] = {"sampled": transaction.is_sampled, "type": transaction.transaction_type} return event_data
def call(self, module, method, wrapped, instance, args, kwargs): span = execution_context.get_span() if span and span.subtype == "aioredis": span.context["destination"] = _get_destination_info(instance) return wrapped(*args, **kwargs)