Skip to content

Commit 1919e9d

Browse files
authored
Merge pull request #2 from Dynatrace/prepare-1.1.0
release 1.1.0
2 parents 8567673 + d1ac21c commit 1919e9d

34 files changed

+2208
-219
lines changed

README.md

Lines changed: 193 additions & 48 deletions
Large diffs are not rendered by default.

docs/conf.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,20 @@
11
#!/usr/bin/env python3
22
# -*- coding: utf-8 -*-
33
#
4+
# Copyright 2018 Dynatrace LLC
5+
#
6+
# Licensed under the Apache License, Version 2.0 (the "License");
7+
# you may not use this file except in compliance with the License.
8+
# You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing, software
13+
# distributed under the License is distributed on an "AS IS" BASIS,
14+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
# See the License for the specific language governing permissions and
16+
# limitations under the License.
17+
418
# OneAgent and SDK for Python documentation build configuration file, created by
519
# sphinx-quickstart on Mon Dec 4 14:43:27 2017.
620
#

docs/encoding.rst

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,32 @@ because most string operations on Python 2 allow mixing :class:`str` and
1515
When passing a :class:`bytes` object (or, equivalently, a :code:`str` object on
1616
Python 2) to a SDK function that says that it accepts a :class:`str`, the bytes
1717
will be interpreted as being UTF-8 encoded. Beware: If the string has invalid
18-
UTF-8 (e.g. Latin-1/ISO-8859-1, as it may occur in :ref:`HTTP headers
18+
UTF-8 (e.g., Latin-1/ISO-8859-1, as it may occur in :ref:`HTTP headers
1919
<http-encoding-warning>`), the function to which it was passed may fail either
2020
partially or fully. Such failures are guaranteed to neither throw exceptions nor
2121
violate any invariants of the involved objects, but some or all of the
22-
information passed in that function call may be lost (E.g. a single invalid HTTP
23-
header passed to :meth:`oneagent.sdk.SDK.trace_incoming_web_request` may cause
24-
an null-tracer to be returned -- but it is also allowed to e.g. truncate that
25-
HTTP header and discard all that follow; the exact failure mode is undefined and
26-
you should take care to not pass invalid strings). Also, the diagnostic callback
22+
information passed in that function call may be lost (for example, a single
23+
invalid HTTP header passed to
24+
:meth:`oneagent.sdk.SDK.trace_incoming_web_request` may cause an null-tracer to
25+
be returned -- but it is also allowed to, for example, truncate that HTTP header
26+
and discard all that follow; the exact failure mode is undefined and you should
27+
take care to not pass invalid strings). Also, the diagnostic callback
2728
(:meth:`oneagent.sdk.SDK.set_diagnostic_callback`) may be invoked (but is not
2829
guaranteed to).
30+
31+
.. _http-encoding-warning:
32+
33+
HTTP Request and Response Header Encoding
34+
-----------------------------------------
35+
36+
The strings passed to the :code:`add_request_header()`, :code:`add_request_headers()`,
37+
:code:`add_parameter()`, :code:`add_parameters()`, :code:`add_response_header()` and
38+
:code:`add_response_headers()` methods of the :class:`oneagent.sdk.tracers.IncomingWebRequestTracer`
39+
and :class:`oneagent.sdk.tracers.OutgoingWebRequestTracer` classes follow the usual SDK
40+
:ref:`encoding <encoding>` conventions, i.e., must be either unicode strings or UTF-8 bytes objects.
41+
42+
.. warning:: However, `HTTP <https://tools.ietf.org/html/rfc7230#section-3.2.4>`_ and `Python's WSGI
43+
<https://www.python.org/dev/peps/pep-3333/#unicode-issues>`_ will use the Latin-1 encoding on
44+
Python 2. Before passing such Python 2 native strings to these methods, use
45+
:code:`s.decode('Latin-1')` (see :meth:`bytes.decode`) to convert the string to unicode, which
46+
can be correctly handled.

docs/sdkref.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Module :code:`oneagent` (initialization)
88
----------------------------------------
99

1010
.. automodule:: oneagent
11-
:members: sdkopts_from_commandline, try_init, shutdown
11+
:members: sdkopts_from_commandline, get_sdk, initialize, shutdown
1212

1313
..
1414
.. autofunction:: oneagent.start_agent

docs/tagging.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,13 @@ The following classes are incoming-taggable:
2222

2323
- :class:`IncomingRemoteCallTracer` /
2424
:meth:`oneagent.sdk.SDK.trace_incoming_remote_call`
25-
- :class:`IncomingWebRequestTracer` /
25+
- :class:`IncomingWebRequestTracer` /
2626
:meth:`oneagent.sdk.SDK.trace_incoming_web_request`
2727

2828
The following classes are :class:`OutgoingTaggable`:
2929

3030
- :class:`OutgoingRemoteCallTracer`
31+
- :class:`OutgoingWebRequestTracer`
3132

3233
You first use either :attr:`OutgoingTaggable.outgoing_dynatrace_string_tag` or
3334
:attr:`OutgoingTaggable.outgoing_dynatrace_byte_tag` to retrieve a string or
@@ -80,7 +81,7 @@ point of view. To change that, you do the following:
8081
The result after doing this could look like this:
8182

8283
.. code-block:: python
83-
:emphasize-lines: 9-10,15,17
84+
:emphasize-lines: 9-10,15,18
8485
8586
from oneagent.sdk import SDK, ChannelType, Channel
8687

pylintrc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ include-naming-hint=y
99
good-names=i,j,e,_
1010

1111
[FORMAT]
12-
max-line-length=80
12+
max-line-length=100
1313

1414
[TYPECHECK]
1515
ignored-classes=oneagent._impl.native.sdkctypesiface.SDKDllInterface
1616
redefining-builtins-modules=oneagent._impl.six.moves
17-
disable=missing-docstring,fixme,too-few-public-methods,missing-return-doc
17+
disable=missing-docstring,fixme,too-few-public-methods,missing-return-doc,useless-object-inheritance

samples/basic-sdk-sample/basic_sdk_sample.py

Lines changed: 82 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,19 @@
11
# -*- coding: utf-8 -*-
2+
#
3+
# Copyright 2018 Dynatrace LLC
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
217
'''This example demonstrates instrumenting a (mocked) application that executes
318
a remote call that sometimes fails and does some database operations.'''
419

@@ -8,14 +23,13 @@
823

924
import oneagent # SDK initialization functions
1025
import oneagent.sdk as onesdk # All other SDK functions.
11-
import logging
1226

1327
try: # Python 2 compatibility.
1428
input = raw_input #pylint:disable=redefined-builtin
1529
except NameError:
1630
pass
1731

18-
getsdk = onesdk.SDK.get # Just to make the code shorter.
32+
getsdk = oneagent.get_sdk # Just to make the code shorter.
1933

2034
def traced_db_operation(dbinfo, sql):
2135
print('+db', dbinfo, sql)
@@ -144,49 +158,103 @@ def mock_incoming_web_request():
144158
wreq.add_response_headers({'Content-Length': '1234'})
145159
wreq.set_status_code(200) # OK
146160

161+
# Add 3 different custom attributes.
162+
sdk.add_custom_request_attribute('custom int attribute', 42)
163+
sdk.add_custom_request_attribute('custom float attribute', 1.778)
164+
sdk.add_custom_request_attribute('custom string attribute', 'snow is falling')
165+
166+
# This call will trigger the diagnostic callback.
167+
sdk.add_custom_request_attribute('another key', None)
168+
169+
def _process_my_outgoing_request(_tag):
170+
pass
171+
172+
def mock_outgoing_web_request():
173+
sdk = getsdk()
174+
175+
# Create tracer and and request headers.
176+
tracer = sdk.trace_outgoing_web_request('http://example.com/their-web-app/bar?foo=foz', 'GET',
177+
headers={'X-not-a-useful-header': 'python-was-here'})
178+
179+
with tracer:
180+
# Now get the outgoing dynatrace tag. You have to add this tag as request header to your
181+
# request if you want that the path is continued on the receiving site. Use the constant
182+
# oneagent.common.DYNATRACE_HTTP_HEADER_NAME as request header name.
183+
tag = tracer.outgoing_dynatrace_string_tag
184+
185+
# Here you process and send your web request.
186+
_process_my_outgoing_request(tag)
187+
188+
# As soon as the response is received, you can add the response headers to the
189+
# tracer and you shouldn't forget to set the status code, too.
190+
tracer.add_response_headers({'Content-Length': '1234'})
191+
tracer.set_status_code(200) # OK
192+
193+
def _diag_callback(text):
194+
print(text)
147195

148196
def main():
149197
print('+main')
150198

151-
oneagent.logger.setLevel(1)
152-
oneagent.logger.addHandler(logging.StreamHandler())
153-
154199
# This gathers arguments prefixed with '--dt_' from sys.argv into the
155-
# returned list. See try_init below.
200+
# returned list. See initialize below.
156201
sdk_options = oneagent.sdkopts_from_commandline(remove=True)
157202

158-
# If you do not call try_init() manually, the first call to
159-
# oneagent.sdk.SDK.get() will attempt to initialize the SDK with default
160-
# options, swallowing any errors, which is why manually calling try_init()
161-
# is recommended.
203+
# Before using the SDK you have to initialize the OneAgent. You can call oneagent.initialize()
204+
# as often as you want, but you also have to call oneagent.shutdown() for every call to
205+
# initialize() as well.
206+
#
162207
# Passing in the sdk_options is entirely optional and usually not required
163208
# as all settings will be automatically provided by the Dynatrace OneAgent
164209
# that is installed on the host.
165-
init_result = oneagent.try_init(sdk_options)
210+
init_result = oneagent.initialize(sdk_options)
166211
try:
167212
if init_result.error is not None:
168213
print('Error during SDK initialization:', init_result.error)
169214

170215
# While not by much, it is a bit faster to cache the result of
171-
# oneagent.sdk.SDK.get() instead of calling the function multiple times.
216+
# oneagent.get_sdk() instead of calling the function multiple times.
172217
sdk = getsdk()
173218

219+
# Set the diagnostic callback.
220+
sdk.set_diagnostic_callback(_diag_callback)
221+
174222
# The agent state is one of the integers in oneagent.sdk.AgentState.
175223
print('Agent state:', sdk.agent_state)
176224

177-
# The agent version is the version of the installed OneAgent, not the
178-
# version of the SDK.
225+
# The instance attribute 'agent_found' indicates whether an agent could be found or not.
226+
print('Agent found:', sdk.agent_found)
227+
228+
# If an agent was found but it is incompatible with this version of the SDK for Python
229+
# then 'agent_is_compatible' would be set to false.
230+
print('Agent is compatible:', sdk.agent_is_compatible)
231+
232+
# The agent version is a string holding both the OneAgent version and the
233+
# OneAgent SDK for C/C++ version separated by a '/'.
179234
print('Agent version:', sdk.agent_version_string)
180235

181236
mock_incoming_web_request()
182237

238+
mock_outgoing_web_request()
239+
183240
# We use trace_incoming_remote_call here, because it is one of the few
184241
# calls that create a new path if none is running yet.
185242
with sdk.trace_incoming_remote_call('main', 'main', 'main'):
243+
# We want to start an asynchronous execution at this time, so we create an
244+
# in-process link which we will use afterwards (or in a different thread).
245+
link = sdk.create_in_process_link()
246+
186247
# Simulate some remote calls
187248
outgoing_remote_call(success=True)
188249
outgoing_remote_call(success=True)
189250
outgoing_remote_call(success=False)
251+
252+
# Now the asynchronous execution starts. So we create an in-process tracer. We're using
253+
# the in-process link which we've created above. This link specifies where the traced
254+
# actions below will show up in the path.
255+
with sdk.trace_in_process_link(link):
256+
outgoing_remote_call(success=True)
257+
190258
print('-main')
191259
input('Now wait until the path appears in the UI...')
192260
finally:

samples/basic-sdk-sample/setup.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,18 @@
11
#!/usr/bin/env python3
2+
#
3+
# Copyright 2018 Dynatrace LLC
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
216

317
import io
418

0 commit comments

Comments
 (0)