-
Notifications
You must be signed in to change notification settings - Fork 426
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #790 from DataDog/0.20-dev
Merge 0.20-dev
- Loading branch information
Showing
21 changed files
with
493 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
""" | ||
Datadog APM traces can be integrated with Logs by first having the tracing | ||
library patch the standard library ``logging`` module and updating the log | ||
formatter used by an application. This feature enables you to inject the current | ||
trace information into a log entry. | ||
Before the trace information can be injected into logs, the formatter has to be | ||
updated to include ``dd.trace_id`` and ``dd.span_id`` attributes from the log | ||
record. The integration with Logs occurs as long as the log entry includes | ||
``dd.trace_id=%(dd.trace_id)s`` and ``dd.span_id=%(dd.span_id)s``. | ||
ddtrace-run | ||
----------- | ||
When using ``ddtrace-run``, enable patching by setting the environment variable | ||
``DD_LOGS_INJECTION=true``. The logger by default will have a format that | ||
includes trace information:: | ||
import logging | ||
from ddtrace import tracer | ||
log = logging.getLogger() | ||
log.level = logging.INFO | ||
@tracer.wrap() | ||
def hello(): | ||
log.info('Hello, World!') | ||
hello() | ||
Manual Instrumentation | ||
---------------------- | ||
If you prefer to instrument manually, patch the logging library then update the | ||
log formatter as in the following example:: | ||
from ddtrace import patch_all; patch_all(logging=True) | ||
import logging | ||
from ddtrace import tracer | ||
FORMAT = ('%(asctime)s %(levelname)s [%(name)s] [%(filename)s:%(lineno)d] ' | ||
'[dd.trace_id=%(dd.trace_id)s dd.span_id=%(dd.span_id)s] ' | ||
'- %(message)s') | ||
logging.basicConfig(format=FORMAT) | ||
log = logging.getLogger() | ||
log.level = logging.INFO | ||
@tracer.wrap() | ||
def hello(): | ||
log.info('Hello, World!') | ||
hello() | ||
""" | ||
|
||
from ...utils.importlib import require_modules | ||
|
||
|
||
required_modules = ['logging'] | ||
|
||
with require_modules(required_modules) as missing_modules: | ||
if not missing_modules: | ||
from .patch import patch, unpatch | ||
|
||
__all__ = ['patch', 'unpatch'] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import logging | ||
from wrapt import wrap_function_wrapper as _w | ||
|
||
from ddtrace import config | ||
|
||
from ...helpers import get_correlation_ids | ||
from ...utils.wrappers import unwrap as _u | ||
|
||
RECORD_ATTR_TRACE_ID = 'dd.trace_id' | ||
RECORD_ATTR_SPAN_ID = 'dd.span_id' | ||
RECORD_ATTR_VALUE_NULL = 0 | ||
|
||
config._add('logging', dict( | ||
tracer=None, # by default, override here for custom tracer | ||
)) | ||
|
||
|
||
def _w_makeRecord(func, instance, args, kwargs): | ||
record = func(*args, **kwargs) | ||
|
||
# add correlation identifiers to LogRecord | ||
trace_id, span_id = get_correlation_ids(tracer=config.logging.tracer) | ||
if trace_id and span_id: | ||
setattr(record, RECORD_ATTR_TRACE_ID, trace_id) | ||
setattr(record, RECORD_ATTR_SPAN_ID, span_id) | ||
else: | ||
setattr(record, RECORD_ATTR_TRACE_ID, RECORD_ATTR_VALUE_NULL) | ||
setattr(record, RECORD_ATTR_SPAN_ID, RECORD_ATTR_VALUE_NULL) | ||
|
||
return record | ||
|
||
|
||
def patch(): | ||
""" | ||
Patch ``logging`` module in the Python Standard Library for injection of | ||
tracer information by wrapping the base factory method ``Logger.makeRecord`` | ||
""" | ||
if getattr(logging, '_datadog_patch', False): | ||
return | ||
setattr(logging, '_datadog_patch', True) | ||
|
||
_w(logging.Logger, 'makeRecord', _w_makeRecord) | ||
|
||
|
||
def unpatch(): | ||
if getattr(logging, '_datadog_patch', False): | ||
setattr(logging, '_datadog_patch', False) | ||
|
||
_u(logging.Logger, 'makeRecord') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
""" | ||
The ``mako`` integration traces templates rendering. | ||
Auto instrumentation is available using the ``patch``. The following is an example:: | ||
from ddtrace import patch | ||
from mako.template import Template | ||
patch(mako=True) | ||
t = Template(filename="index.html") | ||
""" | ||
from ..util import require_modules | ||
|
||
required_modules = ['mako'] | ||
|
||
with require_modules(required_modules) as missing_modules: | ||
if not missing_modules: | ||
from .patch import patch, unpatch | ||
|
||
__all__ = [ | ||
'patch', | ||
'unpatch', | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
DEFAULT_TEMPLATE_NAME = '<memory>' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import mako | ||
from mako.template import Template | ||
from wrapt import wrap_function_wrapper as _w | ||
|
||
from ...ext import http | ||
from ...pin import Pin | ||
from ...utils.importlib import func_name | ||
from ...utils.wrappers import unwrap as _u | ||
from .constants import DEFAULT_TEMPLATE_NAME | ||
|
||
|
||
def patch(): | ||
if getattr(mako, '__datadog_patch', False): | ||
# already patched | ||
return | ||
setattr(mako, '__datadog_patch', True) | ||
|
||
Pin(service='mako', app='mako', app_type=http.TEMPLATE).onto(Template) | ||
|
||
_w(mako, 'template.Template.render', _wrap_render) | ||
_w(mako, 'template.Template.render_unicode', _wrap_render) | ||
_w(mako, 'template.Template.render_context', _wrap_render) | ||
|
||
|
||
def unpatch(): | ||
if not getattr(mako, '__datadog_patch', False): | ||
return | ||
setattr(mako, '__datadog_patch', False) | ||
|
||
_u(mako.template.Template, 'render') | ||
_u(mako.template.Template, 'render_unicode') | ||
_u(mako.template.Template, 'render_context') | ||
|
||
|
||
def _wrap_render(wrapped, instance, args, kwargs): | ||
pin = Pin.get_from(instance) | ||
if not pin or not pin.enabled(): | ||
return wrapped(*args, **kwargs) | ||
|
||
template_name = instance.filename or DEFAULT_TEMPLATE_NAME | ||
with pin.tracer.trace(func_name(wrapped), pin.service, span_type=http.TEMPLATE) as span: | ||
try: | ||
template = wrapped(*args, **kwargs) | ||
return template | ||
finally: | ||
span.resource = template_name | ||
span.set_tag('mako.template_name', template_name) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.