google-site-verification: google61fe8ba583a51912.html
Dynatrace OneAgent in Java

Introduction to Dynatrace OneAgent

Dynatrace OneAgent provides automatic instrumentation for Java applications, delivering full-stack observability with minimal configuration. It captures metrics, traces, and logs across the entire application stack.

Installation and Setup

Maven Dependencies

<properties> <dynatrace.version>8.277.1.1005</dynatrace.version> </properties> <dependencies> <!-- Dynatrace OneAgent API --> <dependency> <groupId>com.dynatrace.oneagent</groupId> <artifactId>oneagent-sdk</artifactId> <version>${dynatrace.version}</version> </dependency> <!-- Dynatrace OpenTelemetry Bridge --> <dependency> <groupId>com.dynatrace.oneagent</groupId> <artifactId>oneagent-opentelemetry-bridge</artifactId> <version>${dynatrace.version}</version> </dependency> </dependencies>

Docker Deployment

FROM openjdk:17-jdk-slim # Install Dynatrace OneAgent ARG DT_ENVIRONMENT_ID ARG DT_API_TOKEN ARG DT_ONEAGENT_OPTIONS # Download and install OneAgent RUN curl -s -H "Authorization: Api-Token ${DT_API_TOKEN}" \ "https://${DT_ENVIRONMENT_ID}.live.dynatrace.com/api/v1/deployment/installer/agent/oneagent/unix/latest?arch=x86&flavor=default" \ --output /tmp/oneagent.tar.gz && \ tar -xzf /tmp/oneagent.tar.gz -C /opt && \ rm /tmp/oneagent.tar.gz # Set OneAgent environment variables ENV LD_PRELOAD /opt/dynatrace/oneagent/agent/lib64/liboneagentproc.so ENV DT_ONEAGENT_OPTIONS="${DT_ONEAGENT_OPTIONS}" COPY target/my-app.jar /app/my-app.jar ENTRYPOINT ["java", "-jar", "/app/my-app.jar"]

Configuration

application.yml Configuration

dynatrace: oneagent: enabled: true environment-id: ${DT_ENVIRONMENT_ID} api-token: ${DT_API_TOKEN} # OneAgent configuration options options: >- --set-app-log-content-access=true --set-http-server-request-headers=X-Request-ID,X-Trace-ID --set-http-server-response-headers=X-Request-ID --set-log-level=INFO # Custom service properties service: name: order-service version: 1.0.0 technology: java # Custom request attributes request-attributes: enabled: true include-headers: - "X-User-ID" - "X-Session-ID" - "X-Tenant-ID"

Java System Properties

@Configuration public class DynatraceConfig { @PostConstruct public void configureDynatrace() { // Set Dynatrace system properties System.setProperty("dt_connection_environmentid", System.getenv().getOrDefault("DT_ENVIRONMENT_ID", "your-environment-id")); System.setProperty("dt_connection_authtoken", System.getenv().getOrDefault("DT_API_TOKEN", "your-api-token")); // Enable OneAgent features System.setProperty("dt_feature_oneagent_custom_services", "true"); System.setProperty("dt_feature_oneagent_custom_request_attributes", "true"); System.setProperty("dt_capture_correlation_ids", "true"); // Logging configuration System.setProperty("dt_logging_level", "INFO"); System.setProperty("dt_capture_java_method_bci", "true"); } }

Custom Service Instrumentation

OneAgent SDK Integration

@Component public class DynatraceOneAgentService { private final OneAgentSDK oneAgentSDK; private static final Logger logger = LoggerFactory.getLogger(DynatraceOneAgentService.class); public DynatraceOneAgentService() { this.oneAgentSDK = OneAgentSDKFactory.createInstance(); // Verify SDK state SDKStateCallback sdkStateCallback = new SDKStateCallback() { @Override public void onSDKStateChanged(SDKState sdkState) { logger.info("Dynatrace OneAgent SDK state changed: {}", sdkState); } }; oneAgentSDK.addSDKStateCallback(sdkStateCallback); if (oneAgentSDK.getCurrentState() == SDKState.ACTIVE) { logger.info("Dynatrace OneAgent SDK initialized successfully"); } else { logger.warn("Dynatrace OneAgent SDK not active. Current state: {}", oneAgentSDK.getCurrentState()); } } public OneAgentSDK getOneAgentSDK() { return oneAgentSDK; } }

Custom Service Instrumentation

@Service public class OrderProcessingService { private final OneAgentSDK oneAgentSDK; private final Tracer tracer; private static final Logger logger = LoggerFactory.getLogger(OrderProcessingService.class); public OrderProcessingService(DynatraceOneAgentService dynatraceService) { this.oneAgentSDK = dynatraceService.getOneAgentSDK(); this.tracer = oneAgentSDK.traceCustomService("OrderProcessingService", "OrderProcessing"); } @DynatraceTraced(serviceName = "OrderProcessing", methodName = "processOrder") public Order processOrder(OrderRequest request) { // This method will be automatically traced by Dynatrace return executeOrderProcessing(request); } public Order processOrderWithCustomTrace(OrderRequest request) { InProcessLink inProcessLink = oneAgentSDK.createInProcessLink(); String traceId = oneAgentSDK.getDynatraceStringRepresentation(); try { // Start custom service Tracer.ServerlessCallback serverlessCallback = tracer.enterServerless("processOrder", null); // Add custom request attributes oneAgentSDK.addCustomRequestAttribute("order.amount", request.getAmount()); oneAgentSDK.addCustomRequestAttribute("order.currency", request.getCurrency()); oneAgentSDK.addCustomRequestAttribute("order.customer", request.getCustomerId()); // Set trace context MDC.put("dt_trace_id", traceId); MDC.put("dt_span_id", serverlessCallback.getTraceContext().getSpanId()); logger.info("Processing order with Dynatrace trace: {}", traceId); Order order = executeOrderProcessing(request); // Add result as custom attribute oneAgentSDK.addCustomRequestAttribute("order.result", "success"); oneAgentSDK.addCustomRequestAttribute("order.id", order.getId()); return order; } catch (Exception e) { // Report error to Dynatrace oneAgentSDK.addCustomRequestAttribute("order.result", "error"); oneAgentSDK.addCustomRequestAttribute("order.error", e.getMessage()); oneAgentSDK.reportError(e); throw e; } finally { tracer.leave(); MDC.remove("dt_trace_id"); MDC.remove("dt_span_id"); } } public CompletableFuture<Order> processOrderAsync(OrderRequest request) { // Capture context for async operations InProcessLink inProcessLink = oneAgentSDK.createInProcessLink(); return CompletableFuture.supplyAsync(() -> { try { inProcessLink.link(); return processOrderWithCustomTrace(request); } finally { inProcessLink.unlink(); } }); } private Order executeOrderProcessing(OrderRequest request) { // Simulate processing time try { Thread.sleep(100); } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new RuntimeException("Order processing interrupted", e); } return new Order(UUID.randomUUID().toString(), request.getCustomerId(), request.getAmount()); } } // Custom annotation for Dynatrace tracing @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface DynatraceTraced { String serviceName(); String methodName() default ""; boolean captureParameters() default false; }

Database Instrumentation

Custom Database Monitoring

@Repository public class OrderRepository { private final OneAgentSDK oneAgentSDK; private final JdbcTemplate jdbcTemplate; private static final Logger logger = LoggerFactory.getLogger(OrderRepository.class); public OrderRepository(DynatraceOneAgentService dynatraceService, JdbcTemplate jdbcTemplate) { this.oneAgentSDK = dynatraceService.getOneAgentSDK(); this.jdbcTemplate = jdbcTemplate; } public Order findById(String orderId) { DatabaseRequestTracer tracer = oneAgentSDK.traceSQLDatabaseRequest( "OrderRepository", "findById", "orders", "SELECT * FROM orders WHERE id = ?" ); try { tracer.start(); tracer.setParameterData("orderId", orderId); // Execute query List<Order> orders = jdbcTemplate.query( "SELECT * FROM orders WHERE id = ?", new Object[]{orderId}, new OrderRowMapper() ); tracer.setRowsReturned(orders.size()); if (orders.isEmpty()) { tracer.error("Order not found: " + orderId); return null; } return orders.get(0); } catch (Exception e) { tracer.error(e); logger.error("Failed to find order: {}", orderId, e); throw e; } finally { tracer.end(); } } public void saveOrder(Order order) { DatabaseRequestTracer tracer = oneAgentSDK.traceSQLDatabaseRequest( "OrderRepository", "saveOrder", "orders", "INSERT INTO orders (id, customer_id, amount, status) VALUES (?, ?, ?, ?)" ); try { tracer.start(); tracer.setParameterData("orderId", order.getId()); tracer.setParameterData("customerId", order.getCustomerId()); tracer.setParameterData("amount", order.getAmount().toString()); int rowsAffected = jdbcTemplate.update( "INSERT INTO orders (id, customer_id, amount, status) VALUES (?, ?, ?, ?)", order.getId(), order.getCustomerId(), order.getAmount(), "CREATED" ); tracer.setRowsAffected(rowsAffected); } catch (Exception e) { tracer.error(e); logger.error("Failed to save order: {}", order.getId(), e); throw e; } finally { tracer.end(); } } } // Custom DataSource wrapper for Dynatrace monitoring @Component public class DynatraceDataSource extends AbstractDataSource { private final DataSource delegate; private final OneAgentSDK oneAgentSDK; public DynatraceDataSource(DataSource delegate, DynatraceOneAgentService dynatraceService) { this.delegate = delegate; this.oneAgentSDK = dynatraceService.getOneAgentSDK(); } @Override public Connection getConnection() throws SQLException { return new DynatraceConnection(delegate.getConnection(), oneAgentSDK); } @Override public Connection getConnection(String username, String password) throws SQLException { return new DynatraceConnection(delegate.getConnection(username, password), oneAgentSDK); } private static class DynatraceConnection implements Connection { private final Connection delegate; private final OneAgentSDK oneAgentSDK; public DynatraceConnection(Connection delegate, OneAgentSDK oneAgentSDK) { this.delegate = delegate; this.oneAgentSDK = oneAgentSDK; } @Override public PreparedStatement prepareStatement(String sql) throws SQLException { return new DynatracePreparedStatement(delegate.prepareStatement(sql), sql, oneAgentSDK); } // Implement all other Connection methods by delegating to the underlying connection @Override public void close() throws SQLException { delegate.close(); } @Override public boolean isClosed() throws SQLException { return delegate.isClosed(); } // ... implement all other Connection methods } private static class DynatracePreparedStatement implements PreparedStatement { private final PreparedStatement delegate; private final String sql; private final OneAgentSDK oneAgentSDK; private DatabaseRequestTracer tracer; public DynatracePreparedStatement(PreparedStatement delegate, String sql, OneAgentSDK oneAgentSDK) { this.delegate = delegate; this.sql = sql; this.oneAgentSDK = oneAgentSDK; } @Override public ResultSet executeQuery() throws SQLException { startTracer(); try { ResultSet resultSet = delegate.executeQuery(); tracer.setRowsReturned(getRowCount(resultSet)); return resultSet; } catch (SQLException e) { tracer.error(e); throw e; } finally { endTracer(); } } @Override public int executeUpdate() throws SQLException { startTracer(); try { int rowsAffected = delegate.executeUpdate(); tracer.setRowsAffected(rowsAffected); return rowsAffected; } catch (SQLException e) { tracer.error(e); throw e; } finally { endTracer(); } } private void startTracer() { tracer = oneAgentSDK.traceSQLDatabaseRequest("CustomDataSource", "execute", "database", sql); tracer.start(); } private void endTracer() { if (tracer != null) { tracer.end(); tracer = null; } } private int getRowCount(ResultSet resultSet) throws SQLException { int rowCount = 0; if (resultSet != null) { resultSet.last(); rowCount = resultSet.getRow(); resultSet.beforeFirst(); } return rowCount; } // Delegate all other methods @Override public void close() throws SQLException { delegate.close(); } // ... implement all other PreparedStatement methods } }

HTTP Client Instrumentation

RestTemplate with Dynatrace

@Component public class DynatraceRestTemplateInterceptor implements ClientHttpRequestInterceptor { private final OneAgentSDK oneAgentSDK; private static final Logger logger = LoggerFactory.getLogger(DynatraceRestTemplateInterceptor.class); public DynatraceRestTemplateInterceptor(DynatraceOneAgentService dynatraceService) { this.oneAgentSDK = dynatraceService.getOneAgentSDK(); } @Override public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException { String url = request.getURI().toString(); String method = request.getMethod().name(); String host = request.getURI().getHost(); // Create web application tracer WebApplicationTracer tracer = oneAgentSDK.traceWebApplicationRequest( "OutboundHTTP", url, method, host ); try { tracer.start(); // Add Dynatrace headers for distributed tracing tracer.injectTracingHeaders((name, value) -> { request.getHeaders().add(name, value); }); // Add custom attributes tracer.setRemoteAddress(host); tracer.setRemotePort(request.getURI().getPort()); ClientHttpResponse response = execution.execute(request, body); // Set response information tracer.setStatusCode(response.getRawStatusCode()); return response; } catch (IOException e) { tracer.error(e); logger.error("HTTP request failed: {} {}", method, url, e); throw e; } finally { tracer.end(); } } } @Configuration public class RestTemplateConfig { @Bean public RestTemplate restTemplate(DynatraceRestTemplateInterceptor interceptor) { RestTemplate restTemplate = new RestTemplate(); List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>(restTemplate.getInterceptors()); interceptors.add(interceptor); restTemplate.setInterceptors(interceptors); return restTemplate; } }

WebClient Instrumentation

@Component public class DynatraceWebClientFilter { private final OneAgentSDK oneAgentSDK; public DynatraceWebClientFilter(DynatraceOneAgentService dynatraceService) { this.oneAgentSDK = dynatraceService.getOneAgentSDK(); } public ExchangeFilterFunction dynatraceTracingFilter() { return ExchangeFilterFunction.ofRequestProcessor(clientRequest -> { String url = clientRequest.url().toString(); String method = clientRequest.method().name(); String host = clientRequest.url().getHost(); WebApplicationTracer tracer = oneAgentSDK.traceWebApplicationRequest( "OutboundHTTP", url, method, host ); try { tracer.start(); // Inject Dynatrace headers ClientRequest.Builder requestBuilder = ClientRequest.from(clientRequest); tracer.injectTracingHeaders((name, value) -> { requestBuilder.header(name, value); }); return Mono.just(requestBuilder.build()); } catch (Exception e) { tracer.error(e); return Mono.error(e); } finally { tracer.end(); } }); } }

Custom Business Metrics

Custom Metrics and Events

@Service public class BusinessMetricsService { private final OneAgentSDK oneAgentSDK; private static final Logger logger = LoggerFactory.getLogger(BusinessMetricsService.class); // Custom metrics private static final String ORDERS_PROCESSED_METRIC = "orders_processed_total"; private static final String ORDER_VALUE_METRIC = "order_value"; private static final String PROCESSING_TIME_METRIC = "order_processing_time"; public BusinessMetricsService(DynatraceOneAgentService dynatraceService) { this.oneAgentSDK = dynatraceService.getOneAgentSDK(); } public void recordOrderProcessed(String customerId, BigDecimal amount, long processingTimeMs) { try { // Record counter metric oneAgentSDK.recordMetric(ORDERS_PROCESSED_METRIC, 1.0); // Record value metric oneAgentSDK.recordMetric(ORDER_VALUE_METRIC, amount.doubleValue()); // Record timing metric oneAgentSDK.recordMetric(PROCESSING_TIME_METRIC, processingTimeMs); // Add custom request attributes for business analysis oneAgentSDK.addCustomRequestAttribute("order.customer", customerId); oneAgentSDK.addCustomRequestAttribute("order.amount", amount.toString()); oneAgentSDK.addCustomRequestAttribute("order.processing_time_ms", processingTimeMs); } catch (Exception e) { logger.warn("Failed to record business metrics", e); } } public void recordError(String operation, String errorType, String errorMessage) { try { oneAgentSDK.addCustomRequestAttribute("error.operation", operation); oneAgentSDK.addCustomRequestAttribute("error.type", errorType); oneAgentSDK.addCustomRequestAttribute("error.message", errorMessage); } catch (Exception e) { logger.warn("Failed to record error metrics", e); } } public void recordCustomEvent(String eventType, Map<String, String> eventData) { try { CustomEvent event = new CustomEvent(eventType); eventData.forEach(event::put); oneAgentSDK.recordEvent(event); } catch (Exception e) { logger.warn("Failed to record custom event", e); } } public void recordUserAction(String action, String userId, Map<String, String> context) { try { CustomEvent userAction = new CustomEvent("user_action"); userAction.put("action", action); userAction.put("user_id", userId); context.forEach(userAction::put); oneAgentSDK.recordEvent(userAction); } catch (Exception e) { logger.warn("Failed to record user action", e); } } }

Spring Boot Integration

Auto-Configuration

@Configuration @EnableConfigurationProperties(DynatraceProperties.class) @ConditionalOnProperty(name = "dynatrace.oneagent.enabled", havingValue = "true") public class DynatraceAutoConfiguration { @Bean @ConditionalOnMissingBean public DynatraceOneAgentService dynatraceOneAgentService() { return new DynatraceOneAgentService(); } @Bean public DynatraceRestTemplateInterceptor dynatraceRestTemplateInterceptor( DynatraceOneAgentService dynatraceService) { return new DynatraceRestTemplateInterceptor(dynatraceService); } @Bean public BusinessMetricsService businessMetricsService( DynatraceOneAgentService dynatraceService) { return new BusinessMetricsService(dynatraceService); } @Bean public DynatraceWebClientFilter dynatraceWebClientFilter( DynatraceOneAgentService dynatraceService) { return new DynatraceWebClientFilter(dynatraceService); } @Bean public DynatraceAspect dynatraceAspect(DynatraceOneAgentService dynatraceService) { return new DynatraceAspect(dynatraceService); } } @ConfigurationProperties(prefix = "dynatrace.oneagent") public class DynatraceProperties { private boolean enabled = true; private String environmentId; private String apiToken; private String options; private Service service = new Service(); private RequestAttributes requestAttributes = new RequestAttributes(); public static class Service { private String name; private String version; private String technology = "java"; // Getters and setters public String getName() { return name; } public void setName(String name) { this.name = name; } public String getVersion() { return version; } public void setVersion(String version) { this.version = version; } public String getTechnology() { return technology; } public void setTechnology(String technology) { this.technology = technology; } } public static class RequestAttributes { private boolean enabled = true; private List<String> includeHeaders = new ArrayList<>(); // Getters and setters public boolean isEnabled() { return enabled; } public void setEnabled(boolean enabled) { this.enabled = enabled; } public List<String> getIncludeHeaders() { return includeHeaders; } public void setIncludeHeaders(List<String> includeHeaders) { this.includeHeaders = includeHeaders; } } // Getters and setters for main class public boolean isEnabled() { return enabled; } public void setEnabled(boolean enabled) { this.enabled = enabled; } public String getEnvironmentId() { return environmentId; } public void setEnvironmentId(String environmentId) { this.environmentId = environmentId; } public String getApiToken() { return apiToken; } public void setApiToken(String apiToken) { this.apiToken = apiToken; } public String getOptions() { return options; } public void setOptions(String options) { this.options = options; } public Service getService() { return service; } public void setService(Service service) { this.service = service; } public RequestAttributes getRequestAttributes() { return requestAttributes; } public void setRequestAttributes(RequestAttributes requestAttributes) { this.requestAttributes = requestAttributes; } }

Aspect-Oriented Instrumentation

@Aspect @Component public class DynatraceAspect { private final DynatraceOneAgentService dynatraceService; private static final Logger logger = LoggerFactory.getLogger(DynatraceAspect.class); public DynatraceAspect(DynatraceOneAgentService dynatraceService) { this.dynatraceService = dynatraceService; } @Around("@annotation(dynatraceTraced)") public Object traceMethod(ProceedingJoinPoint joinPoint, DynatraceTraced dynatraceTraced) throws Throwable { String serviceName = dynatraceTraced.serviceName(); String methodName = !dynatraceTraced.methodName().isEmpty() ? dynatraceTraced.methodName() : joinPoint.getSignature().getName(); Tracer tracer = dynatraceService.getOneAgentSDK() .traceCustomService(serviceName, methodName); long startTime = System.currentTimeMillis(); try { tracer.enter(); // Capture method parameters if enabled if (dynatraceTraced.captureParameters()) { captureMethodParameters(joinPoint); } Object result = joinPoint.proceed(); // Record success metrics recordMethodSuccess(serviceName, methodName, System.currentTimeMillis() - startTime); return result; } catch (Exception e) { // Record error metrics recordMethodError(serviceName, methodName, e, System.currentTimeMillis() - startTime); dynatraceService.getOneAgentSDK().reportError(e); throw e; } finally { tracer.leave(); } } @Around("execution(* com.myapp.service.*.*(..))") public Object traceServiceMethods(ProceedingJoinPoint joinPoint) throws Throwable { String className = joinPoint.getTarget().getClass().getSimpleName(); String methodName = joinPoint.getSignature().getName(); Tracer tracer = dynatraceService.getOneAgentSDK() .traceCustomService(className, methodName); try { tracer.enter(); return joinPoint.proceed(); } finally { tracer.leave(); } } private void captureMethodParameters(ProceedingJoinPoint joinPoint) { Object[] args = joinPoint.getArgs(); for (int i = 0; i < args.length; i++) { if (args[i] != null) { dynatraceService.getOneAgentSDK().addCustomRequestAttribute( "param." + i, args[i].toString() ); } } } private void recordMethodSuccess(String serviceName, String methodName, long duration) { try { dynatraceService.getOneAgentSDK().addCustomRequestAttribute( serviceName + "." + methodName + ".duration", duration ); dynatraceService.getOneAgentSDK().addCustomRequestAttribute( serviceName + "." + methodName + ".result", "success" ); } catch (Exception e) { logger.warn("Failed to record method success metrics", e); } } private void recordMethodError(String serviceName, String methodName, Exception error, long duration) { try { dynatraceService.getOneAgentSDK().addCustomRequestAttribute( serviceName + "." + methodName + ".duration", duration ); dynatraceService.getOneAgentSDK().addCustomRequestAttribute( serviceName + "." + methodName + ".result", "error" ); dynatraceService.getOneAgentSDK().addCustomRequestAttribute( serviceName + "." + methodName + ".error", error.getClass().getSimpleName() ); } catch (Exception e) { logger.warn("Failed to record method error metrics", e); } } }

Log Integration

MDC Integration with Dynatrace

@Component public class DynatraceMDCIntegration { private final DynatraceOneAgentService dynatraceService; public DynatraceMDCIntegration(DynatraceOneAgentService dynatraceService) { this.dynatraceService = dynatraceService; } public void updateMDCWithDynatraceContext() { try { OneAgentSDK oneAgentSDK = dynatraceService.getOneAgentSDK(); // Get Dynatrace trace context String traceId = oneAgentSDK.getDynatraceStringRepresentation(); // Update MDC with Dynatrace context MDC.put("dt.trace_id", traceId); // Add custom request attributes to MDC for logging Map<String, Object> customAttributes = getCustomAttributes(); customAttributes.forEach((key, value) -> { if (value != null) { MDC.put("dt." + key, value.toString()); } }); } catch (Exception e) { // Log warning but don't break application LoggerFactory.getLogger(DynatraceMDCIntegration.class) .warn("Failed to update MDC with Dynatrace context", e); } } public void clearDynatraceMDC() { // Remove all Dynatrace-related MDC entries MDC.getCopyOfContextMap().keySet().stream() .filter(key -> key.startsWith("dt.")) .forEach(MDC::remove); } private Map<String, Object> getCustomAttributes() { // This would typically retrieve current custom request attributes // For simplicity, return empty map return Collections.emptyMap(); } }

Testing and Validation

Test Configuration

@SpringBootTest @TestPropertySource(properties = { "dynatrace.oneagent.enabled=true", "dynatrace.oneagent.service.name=test-service", "dynatrace.oneagent.service.version=1.0.0" }) public class DynatraceIntegrationTest { @Autowired private DynatraceOneAgentService dynatraceService; @Autowired private BusinessMetricsService businessMetricsService; @Test public void testOneAgentSDKInitialization() { OneAgentSDK oneAgentSDK = dynatraceService.getOneAgentSDK(); assertNotNull(oneAgentSDK); SDKState state = oneAgentSDK.getCurrentState(); assertTrue(state == SDKState.ACTIVE || state == SDKState.TEMPORARY_INACTIVE); } @Test public void testCustomServiceTracing() { OneAgentSDK oneAgentSDK = dynatraceService.getOneAgentSDK(); Tracer tracer = oneAgentSDK.traceCustomService("TestService", "testMethod"); try { tracer.enter(); // Simulate work Thread.sleep(50); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } finally { tracer.leave(); } } @Test public void testBusinessMetricsRecording() { businessMetricsService.recordOrderProcessed("customer123", new BigDecimal("99.99"), 150L); // Verify metrics were recorded (this would typically be verified in Dynatrace UI) } @Test public void testErrorReporting() { OneAgentSDK oneAgentSDK = dynatraceService.getOneAgentSDK(); try { throw new RuntimeException("Test error for Dynatrace"); } catch (RuntimeException e) { oneAgentSDK.reportError(e); } } }

Kubernetes Deployment

Deployment Configuration

apiVersion: apps/v1 kind: Deployment metadata: name: order-service labels: app: order-service spec: replicas: 3 selector: matchLabels: app: order-service template: metadata: labels: app: order-service annotations: dynatrace.com/inject: "true" spec: containers: - name: order-service image: my-registry/order-service:latest env: - name: DT_ENVIRONMENT_ID valueFrom: secretKeyRef: name: dynatrace-secrets key: environmentId - name: DT_API_TOKEN valueFrom: secretKeyRef: name: dynatrace-secrets key: apiToken - name: DT_ONEAGENT_OPTIONS value: "--set-app-log-content-access=true --set-log-level=INFO" ports: - containerPort: 8080 resources: requests: memory: "512Mi" cpu: "250m" limits: memory: "1Gi" cpu: "500m" --- apiVersion: v1 kind: Secret metadata: name: dynatrace-secrets type: Opaque data: environmentId: <base64-encoded-environment-id> apiToken: <base64-encoded-api-token>

Conclusion

Dynatrace OneAgent provides comprehensive observability for Java applications:

  1. Automatic Instrumentation - Zero-code monitoring for common frameworks
  2. Custom Service Monitoring - Fine-grained control over business logic tracing
  3. Database Monitoring - SQL query performance and error tracking
  4. HTTP Client Monitoring - Outbound request tracing and performance
  5. Business Metrics - Custom metrics and events for business analysis
  6. Distributed Tracing - End-to-end transaction tracking across services
  7. Error Reporting - Automatic error detection and reporting

The integration enables full-stack observability with minimal code changes while providing the flexibility to add custom instrumentation for specific business requirements.

Leave a Reply

Your email address will not be published. Required fields are marked *


Macro Nepal Helper