Skip to content

Commit 353d698

Browse files
authored
Merge branch 'census-instrumentation:master' into master
2 parents 59e7e11 + aa1b4ee commit 353d698

File tree

10 files changed

+175
-21
lines changed

10 files changed

+175
-21
lines changed

.github/workflows/build.yml

+19-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ jobs:
1313
runs-on: ubuntu-20.04
1414
env:
1515
# We use these variables to convert between tox and GHA version literals
16-
py27: 2.7
1716
py35: 3.5
1817
py36: 3.6
1918
py37: 3.7
@@ -23,7 +22,7 @@ jobs:
2322
# ensures the entire test matrix is run, even if one permutation fails
2423
fail-fast: false
2524
matrix:
26-
python-version: [py27, py35, py36, py37, py38, py39]
25+
python-version: [py35, py36, py37, py38, py39]
2726
steps:
2827
- name: Checkout code
2928
uses: actions/checkout@v2
@@ -42,3 +41,21 @@ jobs:
4241
key: v1-tox-${{ matrix.python-version }}-${{ hashFiles('tox.ini', '**/setup.py') }}
4342
- name: run tox
4443
run: tox -f ${{ matrix.python-version }}
44+
build-27:
45+
runs-on: ubuntu-20.04
46+
container:
47+
image: python:2.7.18-buster
48+
env:
49+
py27: 2.7
50+
steps:
51+
- name: Checkout code
52+
uses: actions/checkout@v2
53+
- name: Install tox
54+
run: pip install -U tox==3.27.1 tox-factor
55+
- name: Cache tox environment
56+
uses: actions/cache@v2
57+
with:
58+
path: .tox
59+
key: v1-tox-27-${{ hashFiles('tox.ini', '**/setup.py') }}
60+
- name: Run tox for Python 2.7
61+
run: tox -f py27

CHANGELOG.md

+10
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,16 @@
22

33
## Unreleased
44

5+
# 0.11.3
6+
Released 2023-09-18
7+
8+
- Updated `azure` modules
9+
10+
# 0.11.2
11+
Released 2023-03-10
12+
13+
- Updated `azure`, `fastapi`,`flask` modules
14+
515
# 0.11.1
616
Released 2023-01-18
717

contrib/opencensus-ext-azure/CHANGELOG.md

+20-2
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,30 @@
22

33
## Unreleased
44

5+
## 1.1.11
6+
7+
Released 2023-10-12
8+
9+
- Add str fallback to envelope serialization
10+
([#1196](https://github.com/census-instrumentation/opencensus-python/pull/1196))
11+
- Remove outerId from exceptiondata
12+
([#1221](https://github.com/census-instrumentation/opencensus-python/pull/1221))
13+
14+
## 1.1.10
15+
16+
Released 2023-09-18
17+
18+
- Add str fallback to envelope serialization
19+
([#1196](https://github.com/census-instrumentation/opencensus-python/pull/1196))
20+
21+
## 1.1.9
22+
23+
Released 2023-03-10
24+
525
- Fix export of exception information in traces
626
([#1187](https://github.com/census-instrumentation/opencensus-python/pull/1187))
727
- Modify metrics exporter to include setting export interval to 60s
828
([#1193](https://github.com/census-instrumentation/opencensus-python/pull/1193))
9-
- Add str fallback to envelope serialization
10-
([#1196](https://github.com/census-instrumentation/opencensus-python/pull/1196))
1129

1230
## 1.1.8
1331

contrib/opencensus-ext-azure/opencensus/ext/azure/common/transport.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -111,13 +111,16 @@ def _transmit(self, envelopes):
111111
token = self.options.credential.get_token(_MONITOR_OAUTH_SCOPE)
112112
headers["Authorization"] = "Bearer {}".format(token.token)
113113
endpoint += '/v2.1/track'
114+
proxies = json.loads(self.options.proxies)
115+
allow_redirects = len(proxies) != 0
116+
114117
response = requests.post(
115118
url=endpoint,
116119
data=json.dumps(envelopes, default=str),
117120
headers=headers,
118121
timeout=self.options.timeout,
119-
proxies=json.loads(self.options.proxies),
120-
allow_redirects=False,
122+
proxies=proxies,
123+
allow_redirects=allow_redirects,
121124
)
122125
except requests.Timeout as ex:
123126
if not self._is_stats_exporter():

contrib/opencensus-ext-azure/opencensus/ext/azure/trace_exporter/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ def span_data_to_envelope(self, sd):
101101
data = ExceptionData(
102102
exceptions=[{
103103
'id': 1,
104-
'outerId': '{}'.format(sd.span_id),
104+
'outerId': 0,
105105
'typeName': sd.attributes.get(ERROR_NAME, ''),
106106
'message': sd.attributes[ERROR_MESSAGE],
107107
'hasFullStack': STACKTRACE in sd.attributes,

contrib/opencensus-ext-fastapi/CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,7 @@
44

55
## 0.1.0
66

7+
Released 2023-03-10
8+
79
- Initial version
10+
([#1124](https://github.com/census-instrumentation/opencensus-python/pull/1124))

contrib/opencensus-ext-flask/CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
## Unreleased
44

5+
## 0.8.2
6+
Released 2023-03-10
7+
58
- Add exception information to span attributes
69
([#1188](https://github.com/census-instrumentation/opencensus-python/pull/1188))
710

contrib/opencensus-ext-grpc/opencensus/ext/grpc/server_interceptor.py

+78-11
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,40 @@
2525
from opencensus.trace import tracer as tracer_module
2626
from opencensus.trace.propagation import binary_format
2727

28-
ATTRIBUTE_COMPONENT = 'COMPONENT'
29-
ATTRIBUTE_ERROR_NAME = 'ERROR_NAME'
30-
ATTRIBUTE_ERROR_MESSAGE = 'ERROR_MESSAGE'
28+
COMPONENT = attributes_helper.COMMON_ATTRIBUTES['COMPONENT']
29+
ERROR_NAME = attributes_helper.COMMON_ATTRIBUTES['ERROR_NAME']
30+
ERROR_MESSAGE = attributes_helper.COMMON_ATTRIBUTES['ERROR_MESSAGE']
31+
32+
HTTP_HOST = attributes_helper.COMMON_ATTRIBUTES['HTTP_HOST']
33+
HTTP_METHOD = attributes_helper.COMMON_ATTRIBUTES['HTTP_METHOD']
34+
HTTP_PATH = attributes_helper.COMMON_ATTRIBUTES['HTTP_PATH']
35+
HTTP_ROUTE = attributes_helper.COMMON_ATTRIBUTES['HTTP_ROUTE']
36+
HTTP_URL = attributes_helper.COMMON_ATTRIBUTES['HTTP_URL']
37+
HTTP_STATUS_CODE = attributes_helper.COMMON_ATTRIBUTES['HTTP_STATUS_CODE']
38+
GRPC_METHOD = attributes_helper.GRPC_ATTRIBUTES['GRPC_METHOD']
39+
3140
RECV_PREFIX = 'Recv'
3241

42+
GRPC_HTTP_STATUS_MAPPING = {
43+
grpc.StatusCode.OK: 200,
44+
grpc.StatusCode.FAILED_PRECONDITION: 400,
45+
grpc.StatusCode.INVALID_ARGUMENT: 400,
46+
grpc.StatusCode.OUT_OF_RANGE: 400,
47+
grpc.StatusCode.UNAUTHENTICATED: 401,
48+
grpc.StatusCode.PERMISSION_DENIED: 403,
49+
grpc.StatusCode.NOT_FOUND: 404,
50+
grpc.StatusCode.ABORTED: 409,
51+
grpc.StatusCode.ALREADY_EXISTS: 409,
52+
grpc.StatusCode.RESOURCE_EXHAUSTED: 429,
53+
grpc.StatusCode.CANCELLED: 499,
54+
grpc.StatusCode.UNKNOWN: 500,
55+
grpc.StatusCode.INTERNAL: 500,
56+
grpc.StatusCode.DATA_LOSS: 500,
57+
grpc.StatusCode.UNIMPLEMENTED: 501,
58+
grpc.StatusCode.UNAVAILABLE: 503,
59+
grpc.StatusCode.DEADLINE_EXCEEDED: 504
60+
}
61+
3362

3463
class OpenCensusServerInterceptor(grpc.ServerInterceptor):
3564
def __init__(self, sampler=None, exporter=None):
@@ -56,6 +85,12 @@ def new_behavior(request_or_iterator, servicer_context):
5685
# invoke the original rpc behavior
5786
response_or_iterator = behavior(request_or_iterator,
5887
servicer_context)
88+
89+
http_status_code = _convert_grpc_code_to_http_status_code(
90+
servicer_context._state.code
91+
)
92+
span.add_attribute(HTTP_STATUS_CODE, http_status_code)
93+
5994
if response_streaming:
6095
response_or_iterator = grpc_utils.wrap_iter_with_message_events( # noqa: E501
6196
request_or_response_iter=response_or_iterator,
@@ -107,28 +142,60 @@ def _start_server_span(self, servicer_context):
107142
)
108143

109144
span.span_kind = span_module.SpanKind.SERVER
145+
146+
grpc_call_details = servicer_context._rpc_event.call_details
147+
grpc_host = grpc_call_details.host.decode('utf-8')
148+
grpc_method = grpc_call_details.method.decode('utf-8')
149+
150+
tracer.add_attribute_to_current_span(
151+
COMPONENT, 'grpc'
152+
)
153+
tracer.add_attribute_to_current_span(
154+
GRPC_METHOD, grpc_method
155+
)
156+
157+
tracer.add_attribute_to_current_span(
158+
HTTP_HOST, grpc_host
159+
)
160+
tracer.add_attribute_to_current_span(
161+
HTTP_METHOD, 'POST'
162+
)
163+
tracer.add_attribute_to_current_span(
164+
HTTP_ROUTE, grpc_method
165+
)
166+
tracer.add_attribute_to_current_span(
167+
HTTP_PATH, grpc_method
168+
)
110169
tracer.add_attribute_to_current_span(
111-
attribute_key=attributes_helper.COMMON_ATTRIBUTES.get(
112-
ATTRIBUTE_COMPONENT),
113-
attribute_value='grpc')
170+
HTTP_URL, 'grpc://' + grpc_host + grpc_method
171+
)
114172

115173
execution_context.set_opencensus_tracer(tracer)
116174
execution_context.set_current_span(span)
117175
return span
118176

119177

178+
def _convert_grpc_code_to_http_status_code(grpc_state_code):
179+
"""
180+
Converts a gRPC state code into the corresponding HTTP response status.
181+
See:
182+
https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto
183+
"""
184+
if grpc_state_code is None:
185+
return 200
186+
else:
187+
return GRPC_HTTP_STATUS_MAPPING.get(grpc_state_code, 500)
188+
189+
120190
def _add_exc_info(span):
121191
exc_type, exc_value, tb = sys.exc_info()
122-
span.add_attribute(
123-
attributes_helper.COMMON_ATTRIBUTES.get(
124-
ATTRIBUTE_ERROR_MESSAGE),
125-
str(exc_value)
126-
)
192+
span.add_attribute(ERROR_MESSAGE, str(exc_value))
127193
span.stack_trace = stack_trace.StackTrace.from_traceback(tb)
128194
span.status = status.Status(
129195
code=code_pb2.UNKNOWN,
130196
message=str(exc_value)
131197
)
198+
span.add_attribute(HTTP_STATUS_CODE, 500)
132199

133200

134201
def _wrap_rpc_behavior(handler, fn):

contrib/opencensus-ext-grpc/tests/test_server_interceptor.py

+35-3
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
import unittest
1616

17+
import grpc
1718
import mock
1819
from google.rpc import code_pb2
1920

@@ -22,6 +23,9 @@
2223
from opencensus.trace import execution_context
2324
from opencensus.trace import span as span_module
2425

26+
MOCK_HOST = b'localhost:5000'
27+
MOCK_METHOD = b'/helloworld.Greeter/SayHello'
28+
2529

2630
class TestOpenCensusServerInterceptor(unittest.TestCase):
2731
def test_constructor(self):
@@ -38,7 +42,10 @@ def test_intercept_service_no_metadata(self):
3842
'.tracer_module.Tracer', MockTracer)
3943
mock_context = mock.Mock()
4044
mock_context.invocation_metadata = mock.Mock(return_value=None)
41-
mock_context._rpc_event.call_details.method = 'hello'
45+
46+
mock_context._rpc_event.call_details.host = MOCK_HOST
47+
mock_context._rpc_event.call_details.method = MOCK_METHOD
48+
mock_context._state.code = grpc.StatusCode.OK
4249
interceptor = server_interceptor.OpenCensusServerInterceptor(
4350
None, None)
4451
mock_handler = mock.Mock()
@@ -53,6 +60,13 @@ def test_intercept_service_no_metadata(self):
5360

5461
expected_attributes = {
5562
'component': 'grpc',
63+
'grpc.method': '/helloworld.Greeter/SayHello',
64+
'http.host': 'localhost:5000',
65+
'http.method': 'POST',
66+
'http.route': '/helloworld.Greeter/SayHello',
67+
'http.path': '/helloworld.Greeter/SayHello',
68+
'http.url': 'grpc://localhost:5000/helloworld.Greeter/SayHello',
69+
'http.status_code': 200
5670
}
5771

5872
self.assertEqual(
@@ -78,7 +92,9 @@ def test_intercept_service(self):
7892
mock_handler.response_streaming = rsp_streaming
7993
mock_continuation = mock.Mock(return_value=mock_handler)
8094

81-
mock_context._rpc_event.call_details.method = 'hello'
95+
mock_context._rpc_event.call_details.host = MOCK_HOST
96+
mock_context._rpc_event.call_details.method = MOCK_METHOD
97+
mock_context._state.code = grpc.StatusCode.OK
8298
interceptor = server_interceptor.OpenCensusServerInterceptor(
8399
None, None)
84100

@@ -89,6 +105,13 @@ def test_intercept_service(self):
89105

90106
expected_attributes = {
91107
'component': 'grpc',
108+
'grpc.method': '/helloworld.Greeter/SayHello',
109+
'http.host': 'localhost:5000',
110+
'http.method': 'POST',
111+
'http.route': '/helloworld.Greeter/SayHello',
112+
'http.path': '/helloworld.Greeter/SayHello',
113+
'http.url': 'grpc://localhost:5000/helloworld.Greeter/SayHello', # noqa: E501
114+
'http.status_code': 200
92115
}
93116

94117
self.assertEqual(
@@ -110,7 +133,9 @@ def test_intercept_handler_exception(self):
110133
None, None)
111134
mock_context = mock.Mock()
112135
mock_context.invocation_metadata = mock.Mock(return_value=None)
113-
mock_context._rpc_event.call_details.method = 'hello'
136+
137+
mock_context._rpc_event.call_details.host = MOCK_HOST
138+
mock_context._rpc_event.call_details.method = MOCK_METHOD
114139
mock_handler = mock.Mock()
115140
mock_handler.request_streaming = req_streaming
116141
mock_handler.response_streaming = rsp_streaming
@@ -128,6 +153,13 @@ def test_intercept_handler_exception(self):
128153

129154
expected_attributes = {
130155
'component': 'grpc',
156+
'grpc.method': '/helloworld.Greeter/SayHello',
157+
'http.host': 'localhost:5000',
158+
'http.method': 'POST',
159+
'http.route': '/helloworld.Greeter/SayHello',
160+
'http.path': '/helloworld.Greeter/SayHello',
161+
'http.url': 'grpc://localhost:5000/helloworld.Greeter/SayHello', # noqa: E501
162+
'http.status_code': 500,
131163
'error.message': 'Test'
132164
}
133165

setup.py

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
'opencensus-context >= 0.2.dev0',
4646
'google-api-core >= 1.0.0, < 2.0.0; python_version<"3.6"',
4747
'google-api-core >= 1.0.0, < 3.0.0; python_version>="3.6"',
48+
"six ~= 1.16",
4849
],
4950
extras_require={},
5051
license='Apache-2.0',

0 commit comments

Comments
 (0)