{"id":20317609,"url":"https://github.com/dynatrace/oneagent-sdk","last_synced_at":"2025-04-11T17:55:47.292Z","repository":{"id":31978835,"uuid":"117681806","full_name":"Dynatrace/OneAgent-SDK","owner":"Dynatrace","description":"Describes technical concepts of Dynatrace OneAgent SDK","archived":false,"fork":false,"pushed_at":"2023-01-10T14:48:02.000Z","size":109,"stargazers_count":20,"open_issues_count":1,"forks_count":5,"subscribers_count":13,"default_branch":"master","last_synced_at":"2025-03-25T13:51:11.936Z","etag":null,"topics":["agent","apm","data-ingestion","dev-program","dynatrace","oneagent","sdk"],"latest_commit_sha":null,"homepage":"https://www.dynatrace.com/support/help/extend-dynatrace/oneagent-sdk/what-is-oneagent-sdk/","language":"Java","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Dynatrace.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-01-16T12:37:39.000Z","updated_at":"2025-01-05T11:43:05.000Z","dependencies_parsed_at":"2023-01-14T20:15:09.858Z","dependency_job_id":null,"html_url":"https://github.com/Dynatrace/OneAgent-SDK","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dynatrace%2FOneAgent-SDK","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dynatrace%2FOneAgent-SDK/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dynatrace%2FOneAgent-SDK/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dynatrace%2FOneAgent-SDK/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Dynatrace","download_url":"https://codeload.github.com/Dynatrace/OneAgent-SDK/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248456295,"owners_count":21106601,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent","apm","data-ingestion","dev-program","dynatrace","oneagent","sdk"],"created_at":"2024-11-14T18:34:11.977Z","updated_at":"2025-04-11T17:55:47.279Z","avatar_url":"https://github.com/Dynatrace.png","language":"Java","readme":"# How to use this repository\n\nThis repository contains the specification of the Dynatrace OneAgent SDK. All interfaces are specified in Java as the language of choice. These interfaces are implemented in different languages. We try to stay as close to the specification as possible, while still ensuring that language specific concepts are used where this makes the interface more usable.\n\nThis repository therefore can be considered a language independent documentation of the SDK's APIs and concepts.\n\n## Table of Contents\n\n* [Dynatrace OneAgent SDK](#oneagentsdk)  \n* [Language specific SDKs](#languagesdks)\n* [API Concepts](#apiconcepts)\n  * [OneAgentSDK object](#oneagentsdkobject)\n  * [Trace Context](#tracecontext)\n  * [Tracers](#tracers)\n  * [Service endpoints and communication endpoints](#endpoints)\n* [Features](#features)\n  * [Trace incoming and outgoing remote calls](#remoting)\n  * [Trace database requests](#database)\n  * [Trace web requests](#webrequests)\n    * [Trace incoming web requests](#inwebrequests)\n    * [Trace outgoing web requests](#outwebrequests)\n  * [Trace in-process asynchronous execution](#in-process-linking)\n  * [Trace messaging](#messaging)\n    * [Trace outgoing messages](#trace-outgoing-messages)\n    * [Trace incoming messages](#trace-incoming-messages)\n  * [Trace custom services](#customservice)\n  * [Add custom request attributes](#scav)\n* [Limits](#limits)\n* [Troubleshooting](#troubleshooting)\n* [Help \u0026 Support](#help)\n* [Further reading](#furtherreading)\n\n\u003ca name=\"oneagentsdk\"\u003e\u003c/a\u003e\n\n## Dynatrace OneAgent SDK\n\nThe Dynatrace OneAgent SDK can be used to add custom instrumentation for proprietary frameworks or programming languages that are not supported out-of-the-box by Dynatrace. The primary purpose of this SDK is to facilitate end-to-end tracing of transactions.\nWhile other tracing frameworks are rather generic, the Dynatrace OneAgent SDK has more semantics to explicitly model remote calls, database requests, web requests, message passing, in-process context passing and more.\n\nIn order to use the Dynatrace OneAgent SDK you need to have access to the source code of the application in question. In languages like Java and Node.js you might have other possibilities to use the SDK even if you do not want or cannot modify the original code (aspects and monkey patching).\n\nOneAgent automatically detects that your application is instrumented with the OneAgent SDK and immediately begins monitoring it. A restart of the application is required following OneAgent installation on the host. For most languages the SDK does not contain much actual implementation as the real work is done by the Dynatrace OneAgent itself. The SDK just acts as an API to the OneAgent.\n\n\u003e Note: The OneAgent SDK is not supported on serverless code modules, including those for AWS Lambda.\n\u003e Consider using [OpenTelemetry](https://www.dynatrace.com/support/help/shortlink/opentel-lambda) instead in these scenarios.\n\n\u003ca name=\"languagesdks\"\u003e\u003c/a\u003e\n\n## Language specific SDKs\n\nThe language specific SDKs are open source and published directly to GitHub, together with technical documentation and sample code.\n\n* [OneAgent SDK for Node.js](https://github.com/Dynatrace/OneAgent-SDK-for-NodeJs)\n* [OneAgent SDK for Java](https://github.com/Dynatrace/OneAgent-SDK-for-Java)\n* [OneAgent SDK for C/C++](https://github.com/Dynatrace/OneAgent-SDK-for-C)\n* [OneAgent SDK for Python](https://github.com/Dynatrace/OneAgent-SDK-for-Python)\n* [OneAgent SDK for .NET](https://github.com/Dynatrace/OneAgent-SDK-for-dotnet)\n\nThe [Java API contained in this repository](https://github.com/Dynatrace/OneAgent-SDK/blob/master/api) is for design reference only. The actual Java API is available in the [OneAgent SDK for Java](https://github.com/Dynatrace/OneAgent-SDK-for-Java).\n\n\u003ca name=\"apiconcepts\"\u003e\u003c/a\u003e\n\n## API Concepts\n\n\u003ca name=\"oneagentsdkobject\"\u003e\u003c/a\u003e\n\n## OneAgentSDK object\n\nAll interactions with the OneAgentSDK are done via a central interface. You can create an instance of this interface via a factory.\n\n```Java\nOneAgentSDK oneAgentSDK = OneAgentSDKFactory.createInstance();\n```\n\nYou can create more than one object of this in your application. This ensures that you do not need to coordinate a singleton behavior across the whole application and that different frameworks can use the SDK independently from each other. The OneAgentSDK object enables you to create Tracers for different aspects of your application.\n\n\u003ca name=\"tracecontext\"\u003e\u003c/a\u003e\n\n## Trace Context\n\nAn instance of the `OneAgentSDK` provides access to `TraceContextInfo` which holds information\nabout the *Trace-Id* and *Span-Id* of the current PurePath node.\nThis information can then be used to provide e.g. additional context in log messages.\n\nPlease note that `TraceContextInfo` is not intended for tagging or context-propagation use cases.\nDedicated APIs (e.g. [remote calls](#remoting) or [web requests](#webreqeusts)) as well as\nbuilt-in OneAgent sensors take care of linking services correctly.\n\n```Java\nTraceContextInfo traceContextInfo = oneAgentSDK.getTraceContextInfo();\nString traceId = traceContextInfo.getTraceId();\nString spanId = traceContextInfo.getSpanId();\nlogger.info(\"[!dt dt.trace_id={},dt.span_id={}] sending request ...\", traceId, spanId);\n```\n\n\u003ca name=\"tracers\"\u003e\u003c/a\u003e\n\n## Tracers\n\nTo trace any kind of call you first need to create a Tracer. The Tracer object represents the logical and physical endpoint that you want to call. A Tracer serves two purposes. On the one hand to time the call (duration, CPU time and more) and on the other to report errors. That is why each Tracer has these three methods. The error method must be called only once, and it must be in between start and end.\n\n```Java\nvoid start();\n\nvoid error(String message);\n\nvoid end();\n```\n\nIt is good practice to use a Tracer with the following pattern:\n\n```Java\ntracer.start();\ntry {\n\t//make the call you want to trace\n} catch (Throwable e) {\n\ttracer.error(e);\n} finally {\n\ttracer.end();\n}\n```\n\nTo allow tracing across process and technology boundaries, tracers can be supplied with so-called tags. Tags are strings or byte arrays generated by the SDK that enable Dynatrace to trace a transaction end-to-end. The user has to take care of transporting the tag from one process to the other.\n\nA Tracer instance can only be used from the thread on which it was created. See [Trace in-process asynchronous execution](#in-process-linking) for tracing across thread boundaries.\n\n\u003ca name=\"endpoints\"\u003e\u003c/a\u003e\n\n## Service name, service endpoints and communication endpoints\n\nDynatrace supports the idea that the same service is deployed in different environments or just multiple times with different configs. One such logical deployment is usually identified some sort of endpoint string, most of times an URL. Therefore you can have the same *service (same name)* with multiple *service endpoints* (deployed instances of the service).\n\nAdditionally you can supply the actual endpoint for the communication channel. This might sound strange until you think about clustered and highly available services. In such a case the same logical endpoint might have multiple communication endpoints. These might even change over time. The communication endpoint allows Dynatrace to understand which process, device or cloud service will receive the request. Thus even if you cannot install a OneAgent on that receiving end, the Dynatrace AI can reason about its impact on your system.\n\nImagine making a call to a cloud based clustered service. You can trace this call with the SDK, but you cannot install a OneAgent on that cloud based service. Due to the distinction of service endpoint and communication endpoint Dynatrace will understand that you are making calls to this service, it will understand that there are multiple instances, and if one of those starts to fail, the Dynatrace AI will be able to tell you about this and the impact this has.\n\nIf you can trace the call end-to-end though, the extra information about the communication endpoint will enable Dynatrace to understand the extra hops in between due to load balancers and proxies, which its AI can use again to better determine the root cause of any issue.\n\nSee \u003ca href=\"https://www.dynatrace.com/support/help/server-side-services/service-analysis/how-do-i-analyze-individual-service-instances/\" target=\"_blank\"\u003eHow do I analyze service instances?\u003c/a\u003e in the Dynatrace product documentation to learn more.\n\n\u003ca name=\"features\"\u003e\u003c/a\u003e\n\n## Features\n\nThe feature sets differ slightly with each language implementation - see the respective language-specific documentation for feature availability. More functionality will be added over time, see \u003ca href=\"https://answers.dynatrace.com/spaces/483/dynatrace-product-ideas/idea/198106/planned-features-for-oneagent-sdk.html\" target=\"_blank\"\u003ePlanned features for OneAgent SDK\u003c/a\u003e for details on upcoming features.\n\n\u003ca name=\"remoting\"\u003e\u003c/a\u003e\n\n### Trace incoming and outgoing remote calls\n\nYou can use the SDK to trace proprietary IPC communication from one process to the other. This will enable you to see full Service Flow, PurePath and Smartscape topology for remoting technologies that Dynatrace is not aware of.\n\nTo trace any kind of remote call you first need to create a Tracer. The Tracer object represents the endpoint that you want to call, as such you need to supply the name of the remote service and remote method. In addition you need to transport the tag in your remote call to the server side if you want to trace it end-to-end.\n\n```Java\nOutgoingRemoteCallTracer tracer = OneAgentSDK.traceOutgoingRemoteCall(\"remoteMethodToCall\", \"RemoteServiceName\", \"rmi://Endpoint/service\", ChannelType.TCP_IP, \"remoteHost:1234\");\n\ntracer.start();\ntry {\n\ttracer.setProtocolName(\"RMI/custom\");\n\tString tag = tracer.getDynatraceStringTag();\n\t// make the call and transport the tag across to the server to link both sides of the remote call together\n} catch (Throwable e) {\n\ttracer.error(e);\n} finally {\n\ttracer.end();\n}\n\n```\n\nOn the server side you need to wrap the handling and processing of your remote call as well. This will not only trace the server side call and everything that happens, it will also connect it to the calling side.\n\n```Java\nIncomingRemoteCallTracer tracer = OneAgentSDK.traceIncomingRemoteCall(\"remoteMethodToCall\", \"RemoteServiceName\", \"rmi://Endpoint/service\");\n\ntracer.setDynatraceStringTag(tag); // link both sides of the remote call together\ntracer.start();\ntry {\n\ttracer.setProtocolName(\"RMI/custom\");\n\tdoSomeWork();\n} catch (Exception e) {\n\ttracer.error(e);\n} finally {\n\ttracer.end();\n}\n```\n\n\u003ca name=\"database\"\u003e\u003c/a\u003e\n\n### Trace database requests\n\nYou can use the SDK to trace database requests that Dynatrace doesn't detect automatically. This will not only enable you to see single SQL statements within the traced requests, it will also extend SmartScape to include the traced database in the topology. This in turn will extend the reach of the Dynatrace AI, because it will baseline the behaviour of every single reported SQL statement and alert you on errors or slowdowns down to the single SQL statement.\n\nTo trace any kind of database request you first need to create a `DatabaseInfo` object. The info object represents the database itself.\n\n```Java\nDatabaseInfo databaseInfo = OneAgentSDK.createDatabaseInfo(\"myDB\", DatabaseVendor.PROGRESS, ChannelType.TCP_IP, \"dbHost:1234\");\n```\n\nTo trace a specific SQL statement you then need to create a Tracer object.\n\n```Java\nString stmt = \"SELECT name FROM User\";\nDatabaseRequestTracer tracer = OneAgentSDK.traceSQLDatabaseRequest(databaseInfo, stmt);\n\ntracer.start();\ntry {\n\tresult = myDB.executeSQL(stmt);\n\ttracer.setRowsReturned(result.rows);\n} catch (Exception e) {\n\ttracer.error(e);\n} finally {\n\ttracer.end();\n}\n```\n\nPlease note that SQL database traces are only created if they occur within some other SDK trace (e.g. incoming remote call)\nor a OneAgent built-in trace (e.g. incoming web request).\n\n\u003ca name=\"webrequests\"\u003e\u003c/a\u003e\n\n### Trace web requests\n\n\u003ca name=\"inwebrequests\"\u003e\u003c/a\u003e\n\n#### Trace incoming web requests\n\nYou can use the SDK to trace incoming web requests. This might be useful if Dynatrace does not support the respective web server framework or language.\n\nTo trace any kind of incoming web request you first need to create a `WebApplicationInfo` object. The info object represents the endpoint of your web server.\n\n```Java\nWebApplicationInfo waInfo = OneAgentSDK.createWebApplicationInfo(\"WebShopProduction\", \"CheckoutService\", \"/api\");\n```\n\nTo trace a specific incoming web request you then need to create a Tracer object.\n\n```Java\nIncomingWebRequestTracer tracer = OneAgentSDK.traceIncomingWebRequest(waInfo, \"https://www.oursupershop.com/api/checkout\", \"POST\")\n\ntracer.setDynatraceStringTag(tag);\ntracer.start();\ntry {\n\tint statusCodeReturnedToClient = processWebRequest(); // link both sides of the web request together\n\ttracer.setStatusCode(statusCodeReturnedToClient);\n} catch (Exception e) {\n\ttracer.error(e);\n} finally {\n\ttracer.end();\n}\n```\n\n\u003ca name=\"outwebrequests\"\u003e\u003c/a\u003e\n\n#### Trace outgoing web requests\n\nYou can use the SDK to trace outgoing web requests. This might be useful if Dynatrace does not support the respective http library or language.\n\nTo trace an outgoing web request you need to create a Tracer object. It is important to include the Dynatrace header. This ensures that tagging with our built-in sensor is working.\n\n```Java\nOutgoingWebRequestTracer tracer = oneAgentSdk.traceOutgoingWebRequest(url, \"GET\");\ntracer.start();\ntry {\n\trequest = MyHttpLibrary.newGetRequest(url);\n\n\t// sending HTTP header OneAgentSDK.DYNATRACE_HTTP_HEADERNAME is necessary for tagging:\n\trequest.addHeader(OneAgentSDK.DYNATRACE_HTTP_HEADERNAME, tracer.getDynatraceStringTag());\n\n\t// provide all request headers to tracer (optional):\n\tfor (Entry\u003cString, String\u003e entry : request.getHeaders().entrySet()) {\n\t\ttracer.addRequestHeader(entry.getKey(), entry.getValue());\n\t}\n\n\tresponse = request.execute();\n\n\tfor (Entry\u003cString, List\u003cString\u003e\u003e entry : response.getHeaders().entrySet()) {\n\t\tfor (String value : entry.getValue()) {\n\t\t\ttracer.addResponseHeader(entry.getKey(), value);\n\t\t}\n\t}\n\ttracer.setStatusCode(response.getResponseCode());\n\n} catch (Exception e) {\n\ttracer.error(e);\n} finally {\n\ttracer.end();\n}\n```\n\n\u003ca name=\"in-process-linking\"\u003e\u003c/a\u003e\n\n### Trace in-process asynchronous execution\n\nYou can use the SDK to trace asynchronous in-process code execution. This might be useful if the OneAgent does not support the threading framework or specific asynchronous libraries. In-process-linking should be used to link other services (Database, web requests, ...) between thread or queueing boundaries currently not supported out-of-the-box by the OneAgent.\n\nTo link asynchronous execution, you need to create an ``InProcessLink``, where async execution forks:\n\n```Java\nInProcessLink inProcessLink = OneAgentSDK.createInProcessLink();\n```\n\nThe provided `InProcessLink` must not be serialized and can only be used inside the process in which it was created. It must be used to start tracing where the async execution takes place:\n\n```Java\nInProcessLinkTracer tracer = oneAgentSDK.traceInProcessLink(inProcessLink);\n\ntracer.start();\ntry {\n\t// do the asynchronous job\n} catch (Exception e) {\n\ttracer.error(e);\n} finally {\n\ttracer.end();\n}\n```\n\n\u003ca name=\"messaging\"\u003e\u003c/a\u003e\n\n### Trace messaging\n\nYou can use the SDK to trace messages sent or received via a messaging system. When tracing messages, we distinguish between:\n\n* sending a message\n* receiving a message\n* processing a received message\n\n#### Trace outgoing messages\n\nAn outgoing message is traced by calling `traceOutgoingMessage()` with a `MessagingSystemInfo` object.  \nThis instance of `MessagingSystemInfo` can be created by calling `createMessagingSystemInfo` with the following arguments:\n\n* `vendorName:` Mandatory - the messaging system vendor name (e.g. RabbitMq, Apache Kafka, ...), which can be a user defined\nstring. If possible, use a constant defined in `MessageSystemVendor`.\n* `destinationName:` Mandatory - the destination name (e.g. queue name, topic name).\n* `destinationType:` Mandatory - specifies the type of the destination. Valid values are defined by the `MessageDestinationType` enum.\n* `channelType`: Mandatory - A value from  the `ChannelType` enum to specify the protocol used as communication channel (e.g. TCP/IP, IN_PROCESS,... ).\n* `channelEndpoint:` Optional - a string describing the endpoint according to the protocol set in `channelType`:\n  * TCP/IP: Host name or IP address of the server-side, may include the port number (e.g., \"1.2.3.4:8080\" or \"example.com:1234\").\n  * UNIX domain sockets: name of the domain socket file.\n  * Named pipes: name of the pipe.\n\nInstances of `MessagingSystemInfo` can and should be reused across tracing calls.\n\nThe result of `traceIncomingMessage()` is a tracer object to be used for further operations related to this particular trace\n(see [Tracers](#tracers) for details).\n\nBesides the common APIs for outgoing tracers, this tracer offers the additional methods `setVendorMessageId()` and\n`setCorrelationId()` which may be used to provide more details about the sent message. Both APIs take a string as a parameter\nwhich may be used to report the `correlationId` or `vendorMessageId` provided by the messaging system.\n\n**Example:**\n\n```Java\nMessagingSystemInfo messagingSystemInfo = oneAgentSDK.createMessagingSystemInfo(\"myMessagingSystem\",\n\t\t\"requestQueue\", MessageDestinationType.QUEUE, ChannelType.TCP_IP, \"localhost:4711\");\nOutgoingMessageTracer tracer = oneAgentSDK.traceOutgoingMessage(messagingSystemInfo);\ntracer.start();\ntry {\n\t// transport the Dynatrace tag along with the message to allow the outgoing message tracer to be linked\n\t// with the message processing tracer on the receiving side\n\tmessageToSend.setHeaderField(\n\t\tOneAgentSDK.DYNATRACE_MESSAGE_PROPERTYNAME, tracer.getDynatraceStringTag());\n\ttheQueue.send(messageToSend);\n\n\t// optional:  add messageid provided from messaging system\n\ttracer.setVendorMessageId(messageToSend.getMessageId());\n\t// optional:  add correlationId\n\ttracer.setCorrelationId(messageToSend.getCorrelationId());\n} catch (Exception e) {\n\ttracer.error(e.getMessage());\n\tLogger.logError(e);\n} finally {\n\ttracer.end();\n}\n```\n\n#### Trace incoming messages\n\nOn the incoming side, we need to distinguish between the blocking receive operation and the processing of the received message.\nTherefore two different tracers are being used: `IncomingMessageReceiveTracer` and `IncomingMessageProcessTracer`.\n\nAn instance of `IncomingMessageReceiveTracer` is created by calling `traceIncomingMessageReceive` and similarly,\n`traceIncomingMessageProcess` must be called to get an instance of `IncomingMessageProcessTracer`.\n\nBoth functions expect an argument of type `MessagingSystemInfo` which is created in the same way as\n[for outgoing messages](#trace-outgoing-messages).\n\nThe result of both `traceIncomingMessageReceive` and `traceIncomingMessageProcess` are tracer objects to be used for further operations related to this trace (see [Tracers](#tracers) for details).\n\nBesides the common APIs for incoming tracers, an instance of `IncomingMessageProcessTracer` offers the same additional\nmethods `setVendorMessageId()` and `setCorrelationId()` as described for [for outgoing messages](#trace-outgoing-messages).\n\n**Example:**\n\n```Java\nMessagingSystemInfo messagingSystemInfo = oneAgentSDK.createMessagingSystemInfo(\"myMessagingSystem\",\n\t\t\"requestQueue\", MessageDestinationType.QUEUE, ChannelType.TCP_IP, \"localhost:4711\");\n\n// message receiving daemon task:\nwhile(true) {\n\tIncomingMessageReceiveTracer receiveTracer =\n\t\toneAgentSDK.traceIncomingMessageReceive(messagingSystemInfo);\n\treceiveTracer.start();\n\ttry {\n\t\t// blocking call - until message is being available:\n\t\tMessage queryMessage = theQueue.receive(\"client queries\");\n\t\tIncomingMessageProcessTracer processTracer = oneAgentSDK\n\t\t\t.traceIncomingMessageProcess(messagingSystemInfo);\n\t\t// retrieve Dynatrace tag created using the outgoing message tracer to link both sides together\n\t\tprocessTracer.setDynatraceStringTag(\n\t\t\tqueryMessage.getHeaderField(OneAgentSDK.DYNATRACE_MESSAGE_PROPERTYNAME));\n\t\tprocessTracer.setVendorMessageId(queryMessage.getMessageId()); // optional\n\t\tprocessTracer.setCorrelationId(queryMessage.getCorrelationId()); // optional\n\t\tprocessTracer.start();\n\t\ttry {\n\t\t\t// do the work ...\n\t\t} catch (Exception e) {\n\t\t\tprocessTracer.error(e.getMessage());\n\t\t\tLogger.logError(e);\n\t\t} finally {\n\t\t\tprocessTracer.end();\n\t\t}\n\t} catch (Exception e) {\n\t\treceiveTracer.error(e.getMessage());\n\t\tLogger.logError(e);\n\t} finally {\n\t\treceiveTracer.end();\n\t}\n}\n```\n\nIn case of a non-blocking receive operation (e.g. via an event handler), there is no need to\nuse `IncomingMessageReceiveTracer` - just trace the processing of the message by using `IncomingMessageProcessTracer`:\n\n**Example:**\n\n```Java\nMessagingSystemInfo messagingSystemInfo = oneAgentSDK.createMessagingSystemInfo(\"myMessagingSystem\",\n\t\"requestQueue\", MessageDestinationType.QUEUE, ChannelType.TCP_IP, \"localhost:4711\");\n\npublic void onMessage(Message message) {\n\tIncomingMessageProcessTracer processTracer = oneAgentSDK\n\t\t.traceIncomingMessageProcess(messagingSystemInfo);\n\t// retrieve Dynatrace tag created using the outgoing message tracer to link both sides together\n\tprocessTracer.setDynatraceStringTag((String)\n\t\tmessage.getObjectProperty(OneAgentSDK.DYNATRACE_MESSAGE_PROPERTYNAME));\n\tprocessTracer.setVendorMessageId(queryMessage.getMessageId()); // optional\n\tprocessTracer.setCorrelationId(queryMessage.getCorrelationId()); // optional\n\tprocessTracer.start();\n\ttry {\n\t\t// do the work ...\n\t} catch (Exception e) {\n\t\tprocessTracer.error(e.getMessage());\n\t\tLogger.logError(e);\n\t} finally {\n\t\tprocessTracer.end();\n\t}\n}\n```\n\n\u003ca name=\"customservice\"\u003e\u003c/a\u003e\n\n### Trace custom services\n\nYou can use the SDK to trace custom service methods. A custom service method is a meaningful part of your code that you want to trace but that does not fit any other tracer. An example could be the callback of a periodic timer.\n\n```Java\nString serviceMethod = \"onTimer\";\nString serviceName = \"PeriodicCleanupTask\";\nCustomServiceTracer tracer = oneAgentSDK.traceCustomService(serviceMethod, serviceName);\ntracer.start();\ntry {\n\tdoMyCleanup();\n} catch (Exception e) {\n\ttracer.error(e.getMessage());\n\tthrow e;\n} finally {\n\ttracer.end();\n}\n```\n\n\u003ca name=\"scav\"\u003e\u003c/a\u003e\n\n### Add custom request attributes\n\nYou can use the SDK to add custom request attributes to the currently traced service. Custom request attributes allow you to do easier/better filtering of your requests in Dynatrace.\n\nAdding custom request attributes to the currently traced service call is pretty simple. Just call one of the ``addCustomRequestAttribute`` methods with your key and value:\n\n```Java\noneAgentSDK.addCustomRequestAttribute(\"region\", \"EMEA\");\noneAgentSDK.addCustomRequestAttribute(\"salesAmount\", 2500);\n```\n\nWhen no service call is being traced, the custom request attributes are dropped.\n\n## Limits\n\n### String length\n\nThere are different length limits for string parameters:\n\n* SQL statements, web request URI and query: 4.096 characters\n* All others: 250 characters\n\nLonger strings will be silently truncated.\n\n\u003ca name=\"troubleshooting\"\u003e\u003c/a\u003e\n\n## Troubleshooting\n\n### Logging callback\n\nThe SDK provides a logging-callback to give information back to the calling application in case of an error. The user application has to provide a callback like the following:\n\n```Java\npublic interface LoggingCallback {\n\n\tvoid warn(String message);\n\n\tvoid error(String message);\n}\n```\n\nIt is set using the `setLoggingCallback` method. In general it is a good idea to forward these logging events to your application specific logging framework.\n\n### Agent log\n\nIn case of issues, where the logging callback doesn't report any errors and the UI doesn't help: check the [agent log](https://www.dynatrace.com/support/help/installation/setup-tips/where-can-i-find-oneagent-files-and-logs/).\n\n\u003ca name=\"help\"\u003e\u003c/a\u003e\n\n## Help \u0026 Support\n\n### Support policy\n\nThe Dynatrace OneAgent SDK has GA status. The features are fully supported by Dynatrace.\n\nDeprecations of APIs will be announced in the release notes of the specific OneAgent SDK (e.g. OneAgent SDK for Java release notes). Deprecated APIs can be removed from newer OneAgent SDK versions after having been deprecated for at least 1 year.\n\nEnd of support announcements for a specific OneAgent SDK version will be announced in the release notes of the specific OneAgent SDK (e.g. OneAgent SDK for Java release notes) at least six months in advance, in the OneAgent release notes as well as on the list of end of support announcements.\n\n### Get Help\n\n* Ask a question in the \u003ca href=\"https://answers.dynatrace.com/spaces/482/view.html\" target=\"_blank\"\u003eproduct forums\u003c/a\u003e\n* Read the \u003ca href=\"https://www.dynatrace.com/support/help/\" target=\"_blank\"\u003eproduct documentation\u003c/a\u003e\n\n**Open a GitHub issue to:**\n\n* Report minor defects, minor items or typos\n* Ask for improvements or changes in the SDK API\n* Ask any questions related to the community effort\n\nSLAs don't apply for GitHub issues.\n\n**Customers can open a ticket on the \u003ca href=\"https://support.dynatrace.com/supportportal/\" target=\"_blank\"\u003eDynatrace support portal\u003c/a\u003e to:**\n\n* Get support from the Dynatrace technical support engineering team\n* Manage and resolve product related technical issues\n\nSLAs apply according to the customer's support level.\n\n\u003ca name=\"furtherreading\"\u003e\u003c/a\u003e\n\n## Further reading\n\n* \u003ca href=\"https://www.dynatrace.com/support/help/extend-dynatrace/oneagent-sdk/what-is-oneagent-sdk/\" target=\"_blank\"\u003eWhat is the OneAgent SDK?\u003c/a\u003e in the Dynatrace documentation\n* \u003ca href=\"https://answers.dynatrace.com/spaces/483/dynatrace-product-ideas/idea/198106/planned-features-for-oneagent-sdk.html\" target=\"_blank\"\u003eFeedback \u0026 Roadmap thread in AnswerHub\u003c/a\u003e\n* \u003ca href=\"https://www.dynatrace.com/news/blog/dynatrace-oneagent-sdk-for-java-end-to-end-monitoring-for-proprietary-java-frameworks/\" target=\"_blank\"\u003eBlog: Dynatrace OneAgent SDK for Java: End-to-end monitoring for proprietary Java frameworks\u003c/a\u003e\n* \u003ca href=\"https://www.dynatrace.com/news/blog/dynatrace-oneagent-sdk-c-service-transaction-monitoring-c-native-applications/\" target=\"_blank\"\u003eBlog: Dynatrace OneAgent SDK for C: Service and transaction monitoring for C++ and other native applications\u003c/a\u003e\n* \u003ca href=\"https://www.dynatrace.com/news/blog/dynatrace-oneagent-sdk-for-node-js-extend-end-to-end-visibility/\" target=\"_blank\"\u003eBlog: Dynatrace OneAgent SDK for Node.js: Extend end-to-end visibility\u003c/a\u003e\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdynatrace%2Foneagent-sdk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdynatrace%2Foneagent-sdk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdynatrace%2Foneagent-sdk/lists"}