def set_transaction_extra_data(self, data, _key=None): transaction = get_transaction() if not transaction: return if not _key: _key = 'extra' transaction.extra[_key] = data
def call_if_sampling(self, module, method, wrapped, instance, args, kwargs): transaction = get_transaction() if not transaction or not transaction.is_sampled: return wrapped(*args, **kwargs) else: return self.call(module, method, wrapped, instance, args, kwargs)
def call_if_sampling(self, module, method, wrapped, instance, args, kwargs): transaction = get_transaction() if not transaction: return wrapped(*args, **kwargs) elif not transaction.is_sampled: args, kwargs = self.mutate_unsampled_call_args( module, method, wrapped, instance, args, kwargs, transaction) return wrapped(*args, **kwargs) else: return self.call(module, method, wrapped, instance, args, kwargs)
def rum_tracing(request): transaction = get_transaction() if transaction and transaction.trace_parent: return { "apm": { "trace_id": transaction.trace_parent.trace_id, # only put the callable into the context to ensure that we only change the span_id if the value # is rendered "span_id": transaction.ensure_parent_id, "is_sampled": transaction.is_sampled, "is_sampled_js": "true" if transaction.is_sampled else "false", } } return {}
def rum_tracing(): """ Adds APM related IDs to the context used for correlating the backend transaction with the RUM transaction """ transaction = get_transaction() if transaction and transaction.trace_parent: return { "apm": { "trace_id": transaction.trace_parent.trace_id, "span_id": lambda: transaction.ensure_parent_id(), "is_sampled": transaction.is_sampled, "is_sampled_js": "true" if transaction.is_sampled else "false", } } return {}
def call(self, module, method, wrapped, instance, args, kwargs): if "method" in kwargs: method = kwargs["method"] else: method = args[0] headers = None if "headers" in kwargs: headers = kwargs["headers"] if headers is None: headers = {} kwargs["headers"] = headers host = instance.host if instance.port != default_ports.get(instance.scheme): host += ":" + str(instance.port) if "url" in kwargs: url = kwargs["url"] else: url = args[1] signature = method.upper() + " " + host url = instance.scheme + "://" + host + url transaction = get_transaction() with capture_span(signature, "ext.http.urllib3", {"url": url}, leaf=True) as span: # if urllib3 has been called in a leaf span, this span might be a DroppedSpan. leaf_span = span while isinstance(leaf_span, DroppedSpan): leaf_span = leaf_span.parent if headers is not None: # It's possible that there are only dropped spans, e.g. if we started dropping spans. # In this case, the transaction.id is used parent_id = leaf_span.id if leaf_span else transaction.id trace_parent = transaction.trace_parent.copy_from( span_id=parent_id, trace_options=TracingOptions(recorded=True)) headers[constants. TRACEPARENT_HEADER_NAME] = trace_parent.to_ascii() return wrapped(*args, **kwargs)
def test_get_transaction_clear(): requests_store = TransactionsStore(lambda: [], 99999) t = requests_store.begin_transaction("test") assert t == get_transaction(clear=True) assert get_transaction() is None
def test_get_transaction(): requests_store = TransactionsStore(lambda: [], 99999) t = requests_store.begin_transaction("test") assert t == get_transaction()
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 = get_transaction() 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.tags: context["tags"] = deepcopy(transaction.tags) # 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) 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, ), 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) transaction = get_transaction() if transaction: if transaction.trace_parent: event_data["trace_id"] = transaction.trace_parent.trace_id event_data["parent_id"] = transaction.id event_data["transaction_id"] = transaction.id return event_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 = get_transaction() if transaction: transaction_context = deepcopy(transaction.context) else: transaction_context = {} event_data = {} if custom is None: custom = {} if not date: date = datetime.datetime.utcnow() 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.tags: context['tags'] = deepcopy(transaction.tags) # 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) 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, ), 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 # Run the data through processors for processor in self.processors: event_data = processor(self, event_data) # Make sure all data is coerced event_data = transform(event_data) if 'exception' in event_data: event_data['exception']['handled'] = bool(handled) event_data.update({ 'timestamp': date.strftime(constants.TIMESTAMP_FORMAT), }) transaction = get_transaction() if transaction: event_data['transaction'] = {'id': transaction.id} return self._build_msg({'errors': [event_data]})
def set_transaction_name(self, name): transaction = get_transaction() if not transaction: return transaction.name = name
def test_get_transaction_clear(): requests_store = Tracer(lambda: [], lambda: [], lambda *args: None) t = requests_store.begin_transaction("test") assert t == get_transaction(clear=True) assert get_transaction() is None