|
12 | 12 | # See the License for the specific language governing permissions and |
13 | 13 | # limitations under the License. |
14 | 14 |
|
| 15 | +import inspect |
15 | 16 | import logging |
16 | 17 | import sys |
17 | 18 |
|
|
24 | 25 | from opencensus.trace import status |
25 | 26 | from opencensus.trace import tracer as tracer_module |
26 | 27 | from opencensus.trace.exporters import print_exporter |
| 28 | +from opencensus.trace.exporters.transports import sync |
27 | 29 | from opencensus.trace.ext import utils |
28 | 30 | from opencensus.trace.propagation import google_cloud_format |
29 | | -from opencensus.trace.samplers import always_on |
| 31 | +from opencensus.trace.samplers import always_on, probability |
| 32 | + |
30 | 33 |
|
31 | 34 | _FLASK_TRACE_HEADER = 'X_CLOUD_TRACE_CONTEXT' |
32 | 35 |
|
33 | 36 | HTTP_METHOD = attributes_helper.COMMON_ATTRIBUTES['HTTP_METHOD'] |
34 | 37 | HTTP_URL = attributes_helper.COMMON_ATTRIBUTES['HTTP_URL'] |
35 | 38 | HTTP_STATUS_CODE = attributes_helper.COMMON_ATTRIBUTES['HTTP_STATUS_CODE'] |
36 | 39 |
|
| 40 | +BLACKLIST_PATHS = 'BLACKLIST_PATHS' |
| 41 | +GCP_EXPORTER_PROJECT = 'GCP_EXPORTER_PROJECT' |
| 42 | +SAMPLING_RATE = 'SAMPLING_RATE' |
| 43 | +TRANSPORT = 'TRANSPORT' |
| 44 | +ZIPKIN_EXPORTER_SERVICE_NAME = 'ZIPKIN_EXPORTER_SERVICE_NAME' |
| 45 | +ZIPKIN_EXPORTER_HOST_NAME = 'ZIPKIN_EXPORTER_HOST_NAME' |
| 46 | +ZIPKIN_EXPORTER_PORT = 'ZIPKIN_EXPORTER_PORT' |
| 47 | + |
37 | 48 | log = logging.getLogger(__name__) |
38 | 49 |
|
39 | 50 |
|
40 | 51 | class FlaskMiddleware(object): |
| 52 | + DEFAULT_SAMPLER = always_on.AlwaysOnSampler |
| 53 | + DEFAULT_EXPORTER = print_exporter.PrintExporter |
| 54 | + DEFAULT_PROPAGATOR = google_cloud_format.GoogleCloudFormatPropagator |
| 55 | + |
41 | 56 | """Flask middleware to automatically trace requests. |
42 | 57 |
|
43 | 58 | :type app: :class: `~flask.Flask` |
@@ -65,22 +80,78 @@ class FlaskMiddleware(object): |
65 | 80 | :class:`.TextFormatPropagator` and |
66 | 81 | :class:`.TraceContextPropagator`. |
67 | 82 | """ |
68 | | - def __init__(self, app, blacklist_paths=None, sampler=None, exporter=None, |
69 | | - propagator=None): |
70 | | - if sampler is None: |
71 | | - sampler = always_on.AlwaysOnSampler() |
72 | | - |
73 | | - if exporter is None: |
74 | | - exporter = print_exporter.PrintExporter() |
75 | | - |
76 | | - if propagator is None: |
77 | | - propagator = google_cloud_format.GoogleCloudFormatPropagator() |
78 | | - |
| 83 | + def __init__(self, app=None, blacklist_paths=None, sampler=None, |
| 84 | + exporter=None, propagator=None): |
79 | 85 | self.app = app |
80 | 86 | self.blacklist_paths = blacklist_paths |
81 | 87 | self.sampler = sampler |
82 | 88 | self.exporter = exporter |
83 | 89 | self.propagator = propagator |
| 90 | + |
| 91 | + if self.app is not None: |
| 92 | + self.init_app(app) |
| 93 | + |
| 94 | + def init_app(self, app): |
| 95 | + self.app = app |
| 96 | + |
| 97 | + # get settings from app config |
| 98 | + settings = self.app.config.get('OPENCENSUS_TRACE', {}) |
| 99 | + |
| 100 | + self.sampler = (self.sampler |
| 101 | + or settings.get('SAMPLER', |
| 102 | + self.DEFAULT_SAMPLER)) |
| 103 | + self.exporter = (self.exporter |
| 104 | + or settings.get('EXPORTER', |
| 105 | + self.DEFAULT_EXPORTER)) |
| 106 | + self.propagator = (self.propagator |
| 107 | + or settings.get('PROPAGATOR', |
| 108 | + self.DEFAULT_PROPAGATOR)) |
| 109 | + |
| 110 | + # get params from app config |
| 111 | + params = self.app.config.get('OPENCENSUS_TRACE_PARAMS', {}) |
| 112 | + |
| 113 | + self.blacklist_paths = params.get(BLACKLIST_PATHS, |
| 114 | + self.blacklist_paths) |
| 115 | + |
| 116 | + # Initialize the sampler |
| 117 | + if not inspect.isclass(self.sampler): |
| 118 | + pass # handling of instantiated sampler |
| 119 | + elif self.sampler.__name__ == 'ProbabilitySampler': |
| 120 | + _rate = params.get(SAMPLING_RATE, |
| 121 | + probability.DEFAULT_SAMPLING_RATE) |
| 122 | + self.sampler = self.sampler(_rate) |
| 123 | + else: |
| 124 | + self.sampler = self.sampler() |
| 125 | + |
| 126 | + transport = params.get(TRANSPORT, sync.SyncTransport) |
| 127 | + |
| 128 | + # Initialize the exporter |
| 129 | + if not inspect.isclass(self.exporter): |
| 130 | + pass # handling of instantiated exporter |
| 131 | + elif self.exporter.__name__ == 'StackdriverExporter': |
| 132 | + _project_id = params.get(GCP_EXPORTER_PROJECT, None) |
| 133 | + self.exporter = self.exporter( |
| 134 | + project_id=_project_id, |
| 135 | + transport=transport) |
| 136 | + elif self.exporter.__name__ == 'ZipkinExporter': |
| 137 | + _zipkin_service_name = params.get( |
| 138 | + ZIPKIN_EXPORTER_SERVICE_NAME, 'my_service') |
| 139 | + _zipkin_host_name = params.get( |
| 140 | + ZIPKIN_EXPORTER_HOST_NAME, 'localhost') |
| 141 | + _zipkin_port = params.get( |
| 142 | + ZIPKIN_EXPORTER_PORT, 9411) |
| 143 | + self.exporter = self.exporter( |
| 144 | + service_name=_zipkin_service_name, |
| 145 | + host_name=_zipkin_host_name, |
| 146 | + port=_zipkin_port, |
| 147 | + transport=transport) |
| 148 | + else: |
| 149 | + self.exporter = self.exporter(transport=transport) |
| 150 | + |
| 151 | + # Initialize the propagator |
| 152 | + if inspect.isclass(self.propagator): |
| 153 | + self.propagator = self.propagator() |
| 154 | + |
84 | 155 | self.setup_trace() |
85 | 156 |
|
86 | 157 | def setup_trace(self): |
|
0 commit comments