Skip to content

Commit 3332293

Browse files
iroquetaBeta Bot
authored andcommitted
Cherry pick branch 'genexuslabs:feature/gxobservability-testing-and-docs' into beta
1 parent 1d96f22 commit 3332293

File tree

11 files changed

+1125
-293
lines changed

11 files changed

+1125
-293
lines changed

common/src/main/java/com/genexus/opentelemetry/OpenTelemetryHelper.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,31 @@
22

33
import io.opentelemetry.api.trace.Span;
44

5+
/**
6+
* Helper class for OpenTelemetry operations.
7+
* Provides utility methods for working with OpenTelemetry.
8+
*/
59
public class OpenTelemetryHelper {
610

11+
/**
12+
* Records an exception on the specified span
13+
*
14+
* @param span the span to record the exception on
15+
* @param exc the exception to record
16+
*/
717
public static void recordException(Span span, Throwable exc) {
818
if (span != null && exc != null) {
919
span.recordException(exc);
1020
}
1121
}
1222

23+
/**
24+
* Records an exception on the current active span
25+
*
26+
* @param exc the exception to record
27+
* @throws NullPointerException if exc is null
28+
*/
1329
public static void recordException(Throwable exc) {
1430
recordException(Span.current(), exc);
1531
}
16-
}
32+
}

gxobservability/README.md

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# GeneXus Observability
2+
3+
A Java library for integrating OpenTelemetry tracing capabilities into GeneXus applications.
4+
5+
## Overview
6+
7+
The GeneXus Observability module provides a wrapper around the OpenTelemetry Java SDK, allowing GeneXus applications to easily implement distributed tracing. It simplifies the process of creating spans, managing trace context, and propagating trace information across service boundaries.
8+
9+
## Features
10+
11+
- Creation and management of spans with different configurations
12+
- Context propagation across service boundaries
13+
- Ability to add and retrieve baggage items (metadata associated with a trace)
14+
- Support for different span types (internal, server, client, producer, consumer)
15+
- Ability to set span attributes, status, and record exceptions
16+
- Automatic configuration from environment variables
17+
18+
## Dependencies
19+
20+
This module depends on the following OpenTelemetry components:
21+
22+
- opentelemetry-api
23+
- opentelemetry-sdk-trace
24+
- opentelemetry-exporter-otlp
25+
- opentelemetry-sdk
26+
- opentelemetry-semconv
27+
- opentelemetry-extension-annotations
28+
- opentelemetry-sdk-extension-autoconfigure
29+
30+
## Main Components
31+
32+
### OtelTracer
33+
34+
The `OtelTracer` class is the main entry point for creating spans. It provides methods to:
35+
36+
- Create spans with different configurations
37+
- Specify parent context
38+
- Link to other spans
39+
- Define span types
40+
41+
### OtelSpan
42+
43+
The `OtelSpan` class wraps an OpenTelemetry Span and provides methods to:
44+
45+
- Set span attributes
46+
- Record exceptions
47+
- Set span status
48+
- Add and retrieve baggage items
49+
- End spans
50+
51+
### GXSpanContext and GXTraceContext
52+
53+
These classes provide wrappers around OpenTelemetry's SpanContext and Context objects, making it easier to handle trace propagation between services.
54+
55+
## Configuration
56+
57+
The module can be configured using environment variables:
58+
59+
- `OTEL_SERVICE_NAME`: Defines the service name for traces
60+
- `OTEL_SERVICE_VERSION`: Defines the service version
61+
- `OTEL_RESOURCE_ATTRIBUTES`: Defines additional resource attributes
62+
- `JAVA_INSTRUMENTATION_SCOPE_NAME`: Override for the instrumentation scope name
63+
- `JAVA_INSTRUMENTATION_SCOPE_VERSION`: Override for the instrumentation scope version
64+
65+
## Usage Examples
66+
67+
### Creating a Simple Span
68+
69+
```java
70+
OtelTracer tracer = new OtelTracer();
71+
OtelSpan span = tracer.createSpan("MyOperation");
72+
try {
73+
// Perform your operation here
74+
span.setStringAttribute("attribute.key", "value");
75+
} catch (Exception e) {
76+
span.recordException(e.getMessage());
77+
span.setStatus((byte)2, "Operation failed"); // Set status to ERROR
78+
} finally {
79+
span.endSpan();
80+
}
81+
```
82+
83+
### Creating a Span with Context Propagation
84+
85+
```java
86+
OtelTracer tracer = new OtelTracer();
87+
OtelSpan parentSpan = tracer.createSpan("ParentOperation");
88+
GXTraceContext context = parentSpan.getGXTraceContext();
89+
90+
// Use the context in a child operation
91+
OtelSpan childSpan = tracer.createSpan("ChildOperation", context, (byte)2); // CLIENT span
92+
childSpan.setStringAttribute("request.id", "12345");
93+
childSpan.endSpan();
94+
95+
parentSpan.endSpan();
96+
```
97+
98+
## Integration with GeneXus
99+
100+
This module is designed to be easily integrated with GeneXus applications, providing tracing capabilities that can be used both in Java-based backend services and in code generated by GeneXus.

gxobservability/pom.xml

Lines changed: 46 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,29 @@
1111
</parent>
1212

1313
<artifactId>gxobservability</artifactId>
14-
<name>GeneXus Observability</name>
14+
<name>GeneXus Observability</name>
1515

1616
<dependencies>
17+
<!-- OpenTelemetry dependencies -->
1718
<dependency>
1819
<groupId>io.opentelemetry</groupId>
1920
<artifactId>opentelemetry-api</artifactId>
21+
<version>${io.opentelemetry.version}</version>
2022
</dependency>
2123
<dependency>
2224
<groupId>io.opentelemetry</groupId>
2325
<artifactId>opentelemetry-sdk-trace</artifactId>
26+
<version>${io.opentelemetry.version}</version>
2427
</dependency>
2528
<dependency>
2629
<groupId>io.opentelemetry</groupId>
2730
<artifactId>opentelemetry-exporter-otlp</artifactId>
31+
<version>${io.opentelemetry.version}</version>
2832
</dependency>
2933
<dependency>
3034
<groupId>io.opentelemetry</groupId>
3135
<artifactId>opentelemetry-sdk</artifactId>
36+
<version>${io.opentelemetry.version}</version>
3237
</dependency>
3338
<dependency>
3439
<groupId>io.opentelemetry</groupId>
@@ -38,24 +43,52 @@
3843
<dependency>
3944
<groupId>io.opentelemetry</groupId>
4045
<artifactId>opentelemetry-extension-annotations</artifactId>
46+
<version>1.18.0</version>
4147
</dependency>
4248
<dependency>
4349
<groupId>io.opentelemetry</groupId>
4450
<artifactId>opentelemetry-sdk-extension-autoconfigure</artifactId>
45-
<version>1.36.0</version>
51+
<version>${io.opentelemetry.version}</version>
52+
</dependency>
53+
54+
<!-- Test dependencies -->
55+
<dependency>
56+
<groupId>org.junit.jupiter</groupId>
57+
<artifactId>junit-jupiter-api</artifactId>
58+
<version>5.8.2</version>
59+
<scope>test</scope>
60+
</dependency>
61+
<dependency>
62+
<groupId>org.junit.jupiter</groupId>
63+
<artifactId>junit-jupiter-engine</artifactId>
64+
<version>5.8.2</version>
65+
<scope>test</scope>
66+
</dependency>
67+
<dependency>
68+
<groupId>org.junit.platform</groupId>
69+
<artifactId>junit-platform-launcher</artifactId>
70+
<version>1.8.2</version>
71+
<scope>test</scope>
72+
</dependency>
73+
<dependency>
74+
<groupId>org.mockito</groupId>
75+
<artifactId>mockito-core</artifactId>
76+
<version>4.5.1</version>
77+
<scope>test</scope>
78+
</dependency>
79+
<dependency>
80+
<groupId>org.mockito</groupId>
81+
<artifactId>mockito-junit-jupiter</artifactId>
82+
<version>4.5.1</version>
83+
<scope>test</scope>
84+
</dependency>
85+
<dependency>
86+
<groupId>io.opentelemetry</groupId>
87+
<artifactId>opentelemetry-sdk-testing</artifactId>
88+
<version>${io.opentelemetry.version}</version>
89+
<scope>test</scope>
4690
</dependency>
4791
</dependencies>
48-
<dependencyManagement>
49-
<dependencies>
50-
<dependency>
51-
<groupId>io.opentelemetry</groupId>
52-
<artifactId>opentelemetry-bom</artifactId>
53-
<version>1.23.0</version>
54-
<type>pom</type>
55-
<scope>import</scope>
56-
</dependency>
57-
</dependencies>
58-
</dependencyManagement>
5992

6093
<build>
6194
<finalName>gxobservability</finalName>
Lines changed: 45 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,55 @@
11
package com.genexus.opentelemetry;
22

33
import io.opentelemetry.api.trace.Span;
4-
import io.opentelemetry.api.trace.Tracer;
5-
import io.opentelemetry.api.GlobalOpenTelemetry;
6-
import io.opentelemetry.api.OpenTelemetry;
7-
import io.opentelemetry.api.trace.StatusCode;
8-
import io.opentelemetry.context.Context;
9-
public class GXSpanContext
10-
{
11-
private io.opentelemetry.api.trace.SpanContext _spanContext;
4+
import io.opentelemetry.api.trace.SpanContext;
125

13-
public io.opentelemetry.api.trace.SpanContext getSpanContext()
14-
{
15-
return _spanContext;
6+
/**
7+
* Wrapper class for OpenTelemetry SpanContext.
8+
* Provides access to trace and span identifiers.
9+
*/
10+
public class GXSpanContext {
11+
private final SpanContext spanContext;
12+
13+
/**
14+
* Returns the underlying OpenTelemetry SpanContext
15+
*
16+
* @return the underlying SpanContext instance
17+
*/
18+
public SpanContext getSpanContext() {
19+
return spanContext;
1620
}
17-
public GXSpanContext(io.opentelemetry.api.trace.SpanContext spanContext)
18-
{
19-
this._spanContext = spanContext;
21+
22+
/**
23+
* Creates a GXSpanContext from an existing SpanContext
24+
*
25+
* @param spanContext the OpenTelemetry SpanContext to wrap
26+
*/
27+
public GXSpanContext(SpanContext spanContext) {
28+
this.spanContext = spanContext;
2029
}
21-
public GXSpanContext()
22-
{
23-
_spanContext = Span.current().getSpanContext();
30+
31+
/**
32+
* Creates a GXSpanContext from the current active span
33+
*/
34+
public GXSpanContext() {
35+
spanContext = Span.current().getSpanContext();
2436
}
25-
public String traceId()
26-
{
27-
return _spanContext.getTraceId();
37+
38+
/**
39+
* Gets the trace ID of the current span context
40+
*
41+
* @return the trace ID as a hexadecimal string
42+
*/
43+
public String traceId() {
44+
return spanContext.getTraceId();
2845
}
29-
public String spanId()
30-
{
31-
return _spanContext.getSpanId();
46+
47+
/**
48+
* Gets the span ID of the current span context
49+
*
50+
* @return the span ID as a hexadecimal string
51+
*/
52+
public String spanId() {
53+
return spanContext.getSpanId();
3254
}
3355
}
Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,29 @@
11
package com.genexus.opentelemetry;
22

3-
import io.opentelemetry.api.trace.Span;
4-
import io.opentelemetry.api.trace.Tracer;
5-
import io.opentelemetry.api.GlobalOpenTelemetry;
6-
import io.opentelemetry.api.OpenTelemetry;
7-
import io.opentelemetry.api.trace.StatusCode;
83
import io.opentelemetry.context.Context;
94

10-
public class GXTraceContext
11-
{
12-
private Context context;
13-
public GXTraceContext(io.opentelemetry.context.Context context)
14-
{
5+
/**
6+
* Wrapper class for OpenTelemetry Context.
7+
* Provides access to trace context for propagation between processes.
8+
*/
9+
public class GXTraceContext {
10+
private final Context context;
11+
12+
/**
13+
* Creates a GXTraceContext from an existing OpenTelemetry Context
14+
*
15+
* @param context the OpenTelemetry Context to wrap
16+
*/
17+
public GXTraceContext(Context context) {
1518
this.context = context;
1619
}
17-
public Context getTraceContext()
18-
{
20+
21+
/**
22+
* Returns the underlying OpenTelemetry Context
23+
*
24+
* @return the underlying Context instance
25+
*/
26+
public Context getTraceContext() {
1927
return this.context;
2028
}
2129
}

0 commit comments

Comments
 (0)