# Copyright 2010 New Relic, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from newrelic.api.application import application_instance from newrelic.api.time_trace import get_linking_metadata from newrelic.api.transaction import current_transaction, record_log_event from newrelic.common.object_wrapper import wrap_function_wrapper, function_wrapper from newrelic.core.config import global_settings try: from urllib import quote except ImportError: from urllib.parse import quote def add_nr_linking_metadata(message): available_metadata = get_linking_metadata() entity_name = quote(available_metadata.get("entity.name", "")) entity_guid = available_metadata.get("entity.guid", "") span_id = available_metadata.get("span.id", "") trace_id = available_metadata.get("trace.id", "") hostname = available_metadata.get("hostname", "") nr_linking_str = "|".join(("NR-LINKING", entity_guid, hostname, trace_id, span_id, entity_name)) return "%s %s|" % (message, nr_linking_str) @function_wrapper def wrap_getMessage(wrapped, instance, args, kwargs): message = wrapped(*args, **kwargs) return add_nr_linking_metadata(message) def bind_callHandlers(record): return record def wrap_callHandlers(wrapped, instance, args, kwargs): transaction = current_transaction() record = bind_callHandlers(*args, **kwargs) logger_name = getattr(instance, "name", None) if logger_name and logger_name.split(".")[0] == "newrelic": return wrapped(*args, **kwargs) if transaction: settings = transaction.settings else: settings = global_settings() # Return early if application logging not enabled if settings and settings.application_logging and settings.application_logging.enabled: level_name = str(getattr(record, "levelname", "UNKNOWN")) if settings.application_logging.metrics and settings.application_logging.metrics.enabled: if transaction: transaction.record_custom_metric("Logging/lines", {"count": 1}) transaction.record_custom_metric("Logging/lines/%s" % level_name, {"count": 1}) else: application = application_instance(activate=False) if application and application.enabled: application.record_custom_metric("Logging/lines", {"count": 1}) application.record_custom_metric("Logging/lines/%s" % level_name, {"count": 1}) if settings.application_logging.forwarding and settings.application_logging.forwarding.enabled: try: message = record.getMessage() record_log_event(message, level_name, int(record.created * 1000)) except Exception: pass if settings.application_logging.local_decorating and settings.application_logging.local_decorating.enabled: record._nr_original_message = record.getMessage record.getMessage = wrap_getMessage(record.getMessage) return wrapped(*args, **kwargs) def instrument_logging(module): if hasattr(module, "Logger"): if hasattr(module.Logger, "callHandlers"): wrap_function_wrapper(module, "Logger.callHandlers", wrap_callHandlers)