Send your **custom traces** to Coralogix using our OpenTelemetry-compatible endpoint.

## Overview

Custom [traces](https://coralogix.com/docs/user-guides/data_exploration/spans/index.md) can be delivered directly to the Coralogix OpenTelemetry-compatible ingress.\[[DOMAIN_VALUE]\]:443 endpoint using any gRPC client, plain HTTP requests (OTLP/HTTP with JSON or binary protobuf payloads), or [OpenTelemetry SDKs](https://opentelemetry.io/docs/concepts/sdk-configuration/).

The examples below guide you using gRPCurl, cURL (OTLP/HTTP with JSON), and the OpenTelemetry **Java** SDK. This is an alternative to using the [OpenTelemetry Collector](https://coralogix.com/docs/opentelemetry/getting-started/index.md).

## Prerequisites

[Git](https://git-scm.com/) and [gRPCurl](https://github.com/fullstorydev/grpcurl) installed.

## Data model

The custom metric API implementation is based on the OpenTelemetry [tracing specification](https://github.com/open-telemetry/opentelemetry-proto/blob/main/opentelemetry/proto/trace/v1/trace.proto). This ensures that our tracing implementation adheres to industry best practices and can seamlessly integrate with other components and tools in the OpenTelemetry ecosystem.

### Example tracing span

```json
{
  "resource_spans": [
    {
      "resource": {
        "attributes": [
          {
            "key": "cx.application.name",
            "value": {
              "string_value": "my-test-application"
            }
          },
          {
            "key": "cx.subsystem.name",
            "value": {
              "string_value": "my-test-subsystem"
            }
          },
          {
            "key": "service.name",
            "value": {
              "string_value": "my-test-service"
            }
          }
        ]
      },
      "scope_spans": [
        {
          "scope": {
            "name": "test"
          },
          "spans": [
            {
              "trace_id": "d0XALf50O6rdjlMxreTJsA==",
              "span_id": "YolJ2eFjJCs=",
              "name": "test-span",
              "kind": "SPAN_KIND_INTERNAL",
              "start_time_unix_nano": "1665753217736722000",
              "end_time_unix_nano": "1665753217737156416",
              "status": {}
            }
          ]
        }
      ]
    }
  ]
}
```

## Sending data with gRPCurl

gRPC is a modern way of calling APIs on top of HTTP/2. Similar to cURL, [gRPCurl](https://github.com/fullstorydev/grpcurl) is a command-line tool used to communicate with gRPC services.

- For the `<open-telemetry-endpoint>` field, select the ingress.\[[DOMAIN_VALUE]\]:443 endpoint that corresponds to your Coralogix [domain](https://coralogix.com/docs/user-guides/account-management/account-settings/coralogix-domain/index.md) using the domain selector at the top of the page.
- For the `<send-your-data-api-key>` field, input your Coralogix [Send-Your-Data API key](https://coralogix.com/docs/user-guides/account-management/api-keys/send-your-data-api-key/index.md).

Assuming the example in the data model is saved as `traces.json`, use the following command to send your data to Coralogix:

```bash
# Clone OpenTelemetry protobuf definitions
git clone https://github.com/open-telemetry/opentelemetry-proto.git
# Send traces to Coralogix 
grpcurl -v -d @ \
  -rpc-header 'Authorization: Bearer <send-your-data-api-key>' \
  -proto opentelemetry-proto/opentelemetry/proto/collector/trace/v1/trace_service.proto \
  -import-path opentelemetry-proto \
  ingress.[[DOMAIN_VALUE]]:443 \
  opentelemetry.proto.collector.trace.v1.TraceService/Export \
  < traces.json
```

Note

Set the `start_time_unix_nano` and the `end_time_unix_nano` in the `traces.json` to a timestamp that is within the last 24 hours.

## Sending data with cURL (OTLP/HTTP)

The same endpoint also accepts [OTLP/HTTP](https://opentelemetry.io/docs/specs/otlp/#otlphttp) requests on the `/v1/traces` path, with the payload encoded either as JSON (`Content-Type: application/json`) or as binary protobuf (`Content-Type: application/x-protobuf`).

The JSON payload follows the [OTLP/JSON mapping](https://github.com/open-telemetry/opentelemetry-proto/blob/main/docs/specification.md#json-protobuf-encoding), which differs from the gRPCurl example above:

- Keys are lowerCamelCase (`startTimeUnixNano`); original snake_case proto field names are not valid and are ignored.
- `traceId` and `spanId` are hex-encoded strings, not base64.
- Enum fields are integers (for example, `kind: 1` instead of `"SPAN_KIND_INTERNAL"`).
- 64-bit integers are decimal strings.

Save the following example as `traces-http.json`:

```json
{
  "resourceSpans": [
    {
      "resource": {
        "attributes": [
          { "key": "cx.application.name", "value": { "stringValue": "my-test-application" } },
          { "key": "cx.subsystem.name", "value": { "stringValue": "my-test-subsystem" } },
          { "key": "service.name", "value": { "stringValue": "my-test-service" } }
        ]
      },
      "scopeSpans": [
        {
          "scope": { "name": "test" },
          "spans": [
            {
              "traceId": "7745c02dfe743baadd8e5331ade4c9b0",
              "spanId": "628949d9e163242b",
              "name": "test-span",
              "kind": 1,
              "startTimeUnixNano": "1665753217736722000",
              "endTimeUnixNano": "1665753217737156416",
              "status": {}
            }
          ]
        }
      ]
    }
  ]
}
```

Then send it to Coralogix:

```bash
curl -v "https://ingress.[[DOMAIN_VALUE]]:443/v1/traces" \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer <send-your-data-api-key>' \
  --data-binary @traces-http.json
```

## Sending data using the OpenTelemetry Java SDK

The example below guides you using OpenTelemetry Java SDK to send your custom traces to Coralogix. Others [SDKs](https://opentelemetry.io/docs/concepts/sdk-configuration/) may also be used.

**STEP 1**. Add the following libraries to your maven pom.xml:

```xml
<dependency>
    <groupId>io.opentelemetry</groupId>
    <artifactId>opentelemetry-sdk-trace</artifactId>
  <version><!-- put a recent version of opentelemetry sdk here --><version>
</dependency>
<dependency>
    <groupId>io.opentelemetry</groupId>
    <artifactId>opentelemetry-exporter-otlp</artifactId>
  <version><!-- put a recent version of opentelemetry sdk her--><version>
</dependency>
```

**STEP 2**. Use this code snippet to create and report a span:

```groovy
SdkTracerProvider traceProvider =
  SdkTracerProvider.builder()
    .addSpanProcessor(BatchSpanProcessor.builder(
      OtlpGrpcSpanExporter.builder()
        .setEndpoint("https://ingress.[[DOMAIN_VALUE]]:443")
        .addHeader("Authorization", "Bearer <send-your-data-api-key>")
        .build()
    ).build())
    .setResource(Resource.create(Attributes.of(
            ResourceAttributes.SERVICE_NAME, "my-test-service",
            AttributeKey.stringKey("cx.application.name"), "my-test-application",
      AttributeKey.stringKey("cx.subsystem.name"), "my-test-subsystem"
        )))
    .build();

Tracer tracer = traceProvider.tracerBuilder("test").build();

Span span = tracer.spanBuilder("test-span")
  .setSpanKind(SpanKind.INTERNAL)
  .startSpan();
span.end();

traceProvider.forceFlush();
```

## Limits & quotas

Coralogix places a **hard limit of 10MB** of data to our OpenTelemetry [endpoints](https://coralogix.com/docs/integrations/coralogix-endpoints/index.md), with a **recommendation of 2MB**.

Limits apply to single requests, regardless of timespan.

## Additional resources

|               |                                                                                             |
| ------------- | ------------------------------------------------------------------------------------------- |
| Documentation | [Coralogix Endpoints](https://coralogix.com/docs/integrations/coralogix-endpoints/index.md) |
| External      | [GitHub](https://github.com/coralogix/custom-traces-examples/tree/master/java)              |
