diff --git a/docs/custom-instrumentation.asciidoc b/docs/custom-instrumentation.asciidoc index 6c58db5708..b381388d45 100644 --- a/docs/custom-instrumentation.asciidoc +++ b/docs/custom-instrumentation.asciidoc @@ -1,12 +1,21 @@ [[instrumenting-custom-code]] === Instrumenting custom code +[float] +[[instrumenting-custom-code-spans]] +==== Creating Additional Spans in a Transaction + Elastic APM instruments a variety of libraries out of the box, but sometimes you need to know how long a specific function took or how often it gets called. -You can apply the `@elasticapm.capture_span()` decorator to achieve exactly that. -It can also be used as a context manager in the following way: +Assuming you're using one of our <>, you can +apply the `@elasticapm.capture_span()` decorator to achieve exactly that. If +you're not using a supported framework, see +<>. + +`elasticapm.capture_span` can be used either as a decorator or as a context +manager. The following example uses it both ways: [source,python] ---- @@ -48,4 +57,50 @@ async def coffee_maker(strength): NOTE: `asyncio` support is only available in Python 3.7+. -See <> for more information on `capture_span`. +See <> for more information on `capture_span`. + +[float] +[[instrumenting-custom-code-transactions]] +==== Creating New Transactions + +It's important to note that `elasticapm.capture_span` only works if there is +an existing transaction. If you're not using one of our <>, you need to create a `Client` object and begin and end the +transactions yourself. You can even utilize the agent's +<>! + +To collect the spans generated by the supported libraries, you need +to invoke `elasticapm.instrument()` (just once, at the initialization stage of +your application) and create at least one transaction. It is up to you to +determine what you consider a transaction within your application -- it can +be the whole execution of the script or a part of it. + +The example below will consider the whole execution as a single transaction +with two HTTP request spans in it. The config for `elasticapm.Client` can be +passed in programmatically, and it will also utilize any config environment +variables available to it automatically. + +[source,python] +---- +import requests +import time +import elasticapm + +def main(): + sess = requests.Session() + for url in [ 'https://www.elastic.co', 'https://benchmarks.elastic.co' ]: + resp = sess.get(url) + time.sleep(1) + +if __name__ == '__main__': + client = elasticapm.Client(service_name="foo", server_url="https://example.com:8200") + elasticapm.instrument() # Only call this once, as early as possible. + client.begin_transaction(transaction_type="script") + main() + client.end_transaction(name=__name__, result="success") +---- + +Note that you don't need to do anything to send the data -- the `Client` object +will handle that before the script exits. Additionally, the `Client` object should +be treated as a singleton -- you should only create one instance and store/pass +around that instance for all transaction handling. diff --git a/docs/how-the-agent-works.asciidoc b/docs/how-the-agent-works.asciidoc index 3c0bdca5d6..796815144f 100644 --- a/docs/how-the-agent-works.asciidoc +++ b/docs/how-the-agent-works.asciidoc @@ -1,7 +1,7 @@ [[how-the-agent-works]] === How the Agent works -To gather APM events (called Transactions and Spans), errors and metrics, +To gather APM events (called transactions and spans), errors and metrics, the Python agent instruments your application in a few different ways. These events, are then sent to the APM Server. The APM Server converts them to a format suitable for Elasticsearch, and sends them to an Elasticsearch cluster. @@ -17,7 +17,7 @@ framework integration, instrumentation, and background collection. To collect data about incoming requests and background tasks, we integrate with frameworks like <>, <> and Celery. Whenever possible, framework integrations make use of hooks and signals provided by the framework. -Examples of this are +Examples of this are: * `request_started`, `request_finished`, and `got_request_exception` signals from `django.core.signals` * `request_started`, `request_finished`, and `got_request_exception` signals from `flask.signals` @@ -31,35 +31,8 @@ E.g. for Django, you need to add `elasticapm.contrib.django` to `INSTALLED_APPS` ==== What if you are not using a framework If you're not using a supported framework, for example, a simple Python script, you can still -leverage the agent's <>. - -In order to collect the Spans generated by the supported libraries, you need to invoke `elasticapm.instrument()` -(just once, at the initalization stage of your application) and create at least one Transaction. -It is up to you to determine what you consider a Transaction within your application -- it can be the whole execution of the -script or a part of it. - -The example below will consider the whole execution as a single transaction with two HTTP request Spans in it. -The `elasticapm.Client` can be setup programmatically or using the environment variables. - -[source,python] ----- -import requests -import time -import elasticapm - -def main(): - sess = requests.Session() - for url in [ 'https://www.elastic.co', 'https://benchmarks.elastic.co' ]: - resp = sess.get(url) - time.sleep(1) - -if __name__ == '__main__': - client = elasticapm.Client() - elasticapm.instrument() - client.begin_transaction('main') - main() - client.end_transaction('main') ----- +leverage the agent's <>. Check out +our docs on <>. [float] [[how-it-works-instrumentation]] diff --git a/docs/set-up.asciidoc b/docs/set-up.asciidoc index 3497ddedfa..ee7fe788c6 100644 --- a/docs/set-up.asciidoc +++ b/docs/set-up.asciidoc @@ -9,7 +9,7 @@ To get you off the ground, we’ve prepared guides for setting up the Agent with * <> * <> -For custom instrumentation, see the <>. +For custom instrumentation, see <>. include::./django.asciidoc[]