Skip to content

Commit

Permalink
Override sampling decision (census-instrumentation#639)
Browse files Browse the repository at this point in the history
Pass span context to samplers to allow them override the "enabled" flag.
  • Loading branch information
c24t authored May 1, 2019
1 parent e2fa221 commit a293c92
Show file tree
Hide file tree
Showing 36 changed files with 299 additions and 274 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
## Unreleased
- Refactored PeriodicTask
([#632](https://github.com/census-instrumentation/opencensus-python/pull/632))
- Make ProbabilitySampler default, change default sampling rate
- Pass span context to samplers, allow samplers to override parent sampling
decision

## 0.5.0
Released 2019-04-24
Expand Down
22 changes: 14 additions & 8 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,10 @@ Installation & basic usage

.. code:: python
from opencensus.trace import tracer as tracer_module
from opencensus.trace.tracer import Tracer
from opencensus.trace.samplers import AlwaysOnSampler
tracer = tracer_module.Tracer()
tracer = Tracer(sampler=AlwaysOnSampler())
.. _pip: https://pip.pypa.io
.. _pipenv: https://docs.pipenv.org/
Expand All @@ -66,10 +67,11 @@ You can collect traces using the ``Tracer`` `context manager`_:

.. code:: python
from opencensus.trace import tracer as tracer_module
from opencensus.trace.tracer import Tracer
from opencensus.trace.samplers import AlwaysOnSampler
# Initialize a tracer, by default using the `PrintExporter`
tracer = tracer_module.Tracer()
tracer = Tracer(sampler=AlwaysOnSampler())
# Example for creating nested spans
with tracer.span(name='span1') as span1:
Expand All @@ -87,10 +89,11 @@ Alternatively, you can explicitly start and end a span:

.. code:: python
from opencensus.trace import tracer as tracer_module
from opencensus.trace.tracer import Tracer
from opencensus.trace.samplers import AlwaysOnSampler
# Initialize a tracer, by default using the `PrintExporter`
tracer = tracer_module.Tracer()
tracer = Tracer(sampler=AlwaysOnSampler())
tracer.start_span(name='span1')
do_something_to_trace()
Expand All @@ -116,8 +119,11 @@ There are several things you can customize in OpenCensus:
other exporters are provided as `extensions <#trace-exporter>`__.

* **Sampler**, which determines how traces are sampled.
The default sampler is ``AlwaysOnSampler``, other samplers include the
``AlwaysOffSampler`` and ``ProbabilitySampler``.
The default sampler is the ``ProbabilitySampler``, which samples (i.e.
enables tracing for) a percentage of all requests. Sampling is deterministic
according to the trace ID. To force sampling for all requests, or to prevent
any request from being sampled, see ``AlwaysOnSampler`` and
``AlwaysOffSampler``.

* **Propagator**, which serializes and deserializes the
``SpanContext`` and its headers. The default propagator is
Expand Down
1 change: 1 addition & 0 deletions contrib/opencensus-ext-django/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Changelog

## Unreleased
- Make ProbabilitySampler default

## 0.3.0
Released 2019-04-24
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@
from opencensus.trace import attributes_helper
from opencensus.trace import execution_context
from opencensus.trace import print_exporter
from opencensus.trace import samplers
from opencensus.trace import span as span_module
from opencensus.trace import tracer as tracer_module
from opencensus.trace import utils
from opencensus.trace.propagation import trace_context_http_header_format
from opencensus.trace.samplers import always_on

try:
from django.utils.deprecation import MiddlewareMixin
Expand Down Expand Up @@ -113,8 +113,8 @@ def __init__(self, get_response=None):
settings = getattr(django.conf.settings, 'OPENCENSUS', {})
settings = settings.get('TRACE', {})

self.sampler = settings.get('SAMPLER', None) or \
always_on.AlwaysOnSampler()
self.sampler = (settings.get('SAMPLER', None)
or samplers.ProbabilitySampler())
if isinstance(self.sampler, six.string_types):
self.sampler = configuration.load(self.sampler)

Expand Down
65 changes: 57 additions & 8 deletions contrib/opencensus-ext-django/tests/test_django_middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@

from opencensus.trace import execution_context
from opencensus.trace import print_exporter
from opencensus.trace import samplers
from opencensus.trace import span as span_module
from opencensus.trace import utils
from opencensus.trace.blank_span import BlankSpan
from opencensus.trace.propagation import trace_context_http_header_format
from opencensus.trace.samplers import always_on


class TestOpencensusMiddleware(unittest.TestCase):
Expand All @@ -46,7 +46,7 @@ def test_constructor_default(self):

middleware = middleware.OpencensusMiddleware()

assert isinstance(middleware.sampler, always_on.AlwaysOnSampler)
assert isinstance(middleware.sampler, samplers.ProbabilitySampler)
assert isinstance(middleware.exporter, print_exporter.PrintExporter)
assert isinstance(
middleware.propagator,
Expand All @@ -59,7 +59,7 @@ def test_configuration(self):
settings = type('Test', (object,), {})
settings.OPENCENSUS = {
'TRACE': {
'SAMPLER': 'opencensus.trace.samplers.always_on.AlwaysOnSampler()', # noqa
'SAMPLER': 'opencensus.trace.samplers.AlwaysOnSampler()', # noqa
'EXPORTER': 'opencensus.trace.print_exporter.PrintExporter()', # noqa
'PROPAGATOR': 'opencensus.trace.propagation.trace_context_http_header_format.TraceContextPropagator()', # noqa
}
Expand All @@ -71,7 +71,7 @@ def test_configuration(self):
with patch_settings:
middleware = middleware.OpencensusMiddleware()

assert isinstance(middleware.sampler, always_on.AlwaysOnSampler)
assert isinstance(middleware.sampler, samplers.AlwaysOnSampler)
assert isinstance(middleware.exporter, print_exporter.PrintExporter)
assert isinstance(
middleware.propagator,
Expand All @@ -88,7 +88,19 @@ def test_process_request(self):
django_request = RequestFactory().get('/', **{
'HTTP_TRACEPARENT': django_trace_id})

middleware_obj = middleware.OpencensusMiddleware()
# Force the test request to be sampled
settings = type('Test', (object,), {})
settings.OPENCENSUS = {
'TRACE': {
'SAMPLER': 'opencensus.trace.samplers.AlwaysOnSampler()', # noqa
}
}
patch_settings = mock.patch(
'django.conf.settings',
settings)

with patch_settings:
middleware_obj = middleware.OpencensusMiddleware()

# test process_request
middleware_obj.process_request(django_request)
Expand Down Expand Up @@ -123,6 +135,7 @@ def test_blacklist_path(self):
settings = type('Test', (object,), {})
settings.OPENCENSUS = {
'TRACE': {
'SAMPLER': 'opencensus.trace.samplers.AlwaysOnSampler()', # noqa
'BLACKLIST_PATHS': blacklist_paths,
'EXPORTER': mock.Mock(),
}
Expand Down Expand Up @@ -176,7 +189,19 @@ def test_process_response(self):
'traceparent': django_trace_id,
})

middleware_obj = middleware.OpencensusMiddleware()
# Force the test request to be sampled
settings = type('Test', (object,), {})
settings.OPENCENSUS = {
'TRACE': {
'SAMPLER': 'opencensus.trace.samplers.AlwaysOnSampler()', # noqa
}
}
patch_settings = mock.patch(
'django.conf.settings',
settings)

with patch_settings:
middleware_obj = middleware.OpencensusMiddleware()

middleware_obj.process_request(django_request)
tracer = middleware._get_current_tracer()
Expand Down Expand Up @@ -216,7 +241,19 @@ def test_process_response_no_get_username(self):
'traceparent': django_trace_id,
})

middleware_obj = middleware.OpencensusMiddleware()
# Force the test request to be sampled
settings = type('Test', (object,), {})
settings.OPENCENSUS = {
'TRACE': {
'SAMPLER': 'opencensus.trace.samplers.AlwaysOnSampler()', # noqa
}
}
patch_settings = mock.patch(
'django.conf.settings',
settings)

with patch_settings:
middleware_obj = middleware.OpencensusMiddleware()

middleware_obj.process_request(django_request)
tracer = middleware._get_current_tracer()
Expand Down Expand Up @@ -254,7 +291,19 @@ def test_process_response_unfinished_child_span(self):
'traceparent': django_trace_id,
})

middleware_obj = middleware.OpencensusMiddleware()
# Force the test request to be sampled
settings = type('Test', (object,), {})
settings.OPENCENSUS = {
'TRACE': {
'SAMPLER': 'opencensus.trace.samplers.AlwaysOnSampler()', # noqa
}
}
patch_settings = mock.patch(
'django.conf.settings',
settings)

with patch_settings:
middleware_obj = middleware.OpencensusMiddleware()

middleware_obj.process_request(django_request)
tracer = middleware._get_current_tracer()
Expand Down
1 change: 1 addition & 0 deletions contrib/opencensus-ext-flask/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Changelog

## Unreleased
- Make ProbabilitySampler default

## 0.3.0
Released 2019-04-24
Expand Down
8 changes: 4 additions & 4 deletions contrib/opencensus-ext-flask/examples/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@
import requests
import sqlalchemy

import hello_world_pb2
import hello_world_pb2_grpc
from opencensus.ext.flask.flask_middleware import FlaskMiddleware
from opencensus.ext.grpc import client_interceptor
from opencensus.ext.stackdriver import trace_exporter as stackdriver_exporter
from opencensus.trace import config_integration
from opencensus.trace.samplers import probability
from opencensus.trace import samplers
import hello_world_pb2
import hello_world_pb2_grpc

INTEGRATIONS = ['mysql', 'postgresql', 'sqlalchemy', 'requests']

Expand All @@ -48,7 +48,7 @@

# Enable tracing, configure the trace params, send traces to Stackdriver Trace
exporter = stackdriver_exporter.StackdriverExporter()
sampler = probability.ProbabilitySampler(rate=1)
sampler = samplers.ProbabilitySampler(rate=1)
middleware = FlaskMiddleware(app, exporter=exporter, sampler=sampler)
config_integration.trace_integrations(INTEGRATIONS)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@
from opencensus.trace import attributes_helper
from opencensus.trace import execution_context
from opencensus.trace import print_exporter
from opencensus.trace import samplers
from opencensus.trace import span as span_module
from opencensus.trace import stack_trace
from opencensus.trace import status
from opencensus.trace import tracer as tracer_module
from opencensus.trace import utils
from opencensus.trace.propagation import trace_context_http_header_format
from opencensus.trace.samplers import always_on

HTTP_METHOD = attributes_helper.COMMON_ATTRIBUTES['HTTP_METHOD']
HTTP_URL = attributes_helper.COMMON_ATTRIBUTES['HTTP_URL']
Expand All @@ -54,8 +54,8 @@ class FlaskMiddleware(object):
:param sampler: A sampler. It should extend from the base
:class:`.Sampler` type and implement
:meth:`.Sampler.should_sample`. Defaults to
:class:`.AlwaysOnSampler`. The rest options are
:class:`.AlwaysOffSampler`, :class:`.FixedRateSampler`.
:class:`.ProbabilitySampler`. Other options include
:class:`.AlwaysOnSampler` and :class:`.AlwaysOffSampler`.
:type exporter: :class:`~opencensus.trace.base_exporter.exporter`
:param exporter: An exporter. Default to
Expand Down Expand Up @@ -90,8 +90,8 @@ def init_app(self, app):
settings = settings.get('TRACE', {})

if self.sampler is None:
self.sampler = settings.get('SAMPLER', None) or \
always_on.AlwaysOnSampler()
self.sampler = (settings.get('SAMPLER', None)
or samplers.ProbabilitySampler())
if isinstance(self.sampler, six.string_types):
self.sampler = configuration.load(self.sampler)

Expand Down
Loading

0 comments on commit a293c92

Please sign in to comment.