Integrations

OTLP Integration

LogPulse natively supports OpenTelemetry Protocol (OTLP) over HTTP for ingesting logs and traces. Send data from any OpenTelemetry SDK or Collector using the standard OTLP/HTTP JSON endpoints. This is the recommended ingestion method for teams using OpenTelemetry.

Overview

LogPulse implements the OTLP/HTTP specification for both logs and traces. The endpoints accept standard ExportLogsServiceRequest and ExportTraceServiceRequest payloads in JSON format. Kubernetes metadata is automatically extracted and stored as dedicated fields for efficient filtering and RBAC.

HTTP
OTLP/HTTP protocol
JSON
JSON encoding
2
Signals (Logs & Traces)
10 MB
Max request body
Note: LogPulse currently supports OTLP/HTTP with JSON encoding. Protobuf encoding and gRPC transport are not yet supported. Configure your OpenTelemetry exporters to use the OTLP/HTTP JSON exporter.

Endpoints

Two OTLP endpoints are available: one for logs and one for traces. Both require authentication via Bearer token and accept JSON-encoded OTLP payloads.

OTLP Logs Endpoint

POST/v1/logs

Accepts an ExportLogsServiceRequest payload. Each log record is converted to a LogPulse log event and stored in the 'main' index with sourcetype 'otlp'.

ParameterValue
Full URLhttps://api.logpulse.io/v1/logs
Content-Typeapplication/json
Body limit10 MB
Rate limit10,000 requests/min
Indexmain
Sourcetypeotlp

OTLP Traces Endpoint

POST/v1/traces

Accepts an ExportTraceServiceRequest payload. Each span is converted to a LogPulse log event and stored in the 'traces' index with sourcetype 'observability_trace'. Span metadata such as trace ID, duration, and status are extracted as searchable attributes.

ParameterValue
Full URLhttps://api.logpulse.io/v1/traces
Content-Typeapplication/json
Body limit10 MB
Rate limit10,000 requests/min
Indextraces
Sourcetypeobservability_trace

Authentication

All OTLP endpoints require a valid API key passed as a Bearer token in the Authorization header. The same API keys used for the REST API work with OTLP endpoints.

Authorization header
Authorization: Bearer YOUR_API_KEY

Create API keys in the LogPulse dashboard under Settings. Each key is scoped to your organization. The API key is validated by computing a SHA-256 hash and looking it up in the database; keys are never stored in plain text.

Warning: Keep your API keys secret. Never expose them in client-side code, public repositories, or logs. If a key is compromised, revoke it immediately from the dashboard. Revoked and expired keys are rejected with a 401 status code.

Logs Schema Mapping

OTLP log records are converted to LogPulse log events using the following field mapping. Resource attributes, scope metadata, and log record attributes are all extracted and merged.

OTLP FieldLogPulse FieldNotes
body.stringValueeventLog message body stored as the event string
body.kvlistValueevent (JSON)Key-value body is serialized to a JSON string
severityNumberlevelMapped to LogPulse level using severity ranges (see table below)
severityTextlevel (fallback)Used as fallback when severityNumber is not present
timeUnixNanotimestampNanosecond precision, converted to ISO 8601
observedTimeUnixNanotimestamp (fallback)Used when timeUnixNano is not present
resource service.namesourceExtracted from resource attributes as log source
scope.namesource (priority)Scope name takes priority over service.name for source field
resource attributesattributes.*Non-k8s resource attributes merged into log attributes
log record attributesattributes.*Log record attributes stored directly
traceIdattributes.trace_idTrace context preserved for correlation
spanIdattributes.span_idSpan context preserved for correlation

Severity Mapping

The OTLP severityNumber is mapped to a LogPulse log level using the OpenTelemetry severity specification ranges:

OTLP SeverityNumberLogPulse Level
1–4trace
5–8debug
9–12info
13–16warn
17–20error
21+fatal
Note: If severityNumber is absent, severityText is used with pattern matching (e.g., text containing 'error' maps to error level). If neither is present, the default level is 'info'.

Body Extraction

The OTLP log record body supports two formats: a simple string value or a key-value list. Both are converted to the LogPulse event field.

String body
{
  "body": {
    "stringValue": "User login successful from 192.168.1.100"
  }
}
Key-value body (converted to JSON)
{
  "body": {
    "kvlistValue": {
      "values": [
        { "key": "action", "value": { "stringValue": "login" } },
        { "key": "ip", "value": { "stringValue": "192.168.1.100" } }
      ]
    }
  }
}
// Stored as: {"action":"login","ip":"192.168.1.100"}

Traces Schema Mapping

Each OTLP span is converted into a LogPulse log event stored in the 'traces' index. The span's metadata is serialized as a JSON event, and key fields are also stored as individual searchable attributes.

OTLP Span FieldLogPulse AttributeNotes
traceIdtrace_idUnique trace identifier (hex string)
spanIdspan_idUnique span identifier (hex string)
parentSpanIdparent_span_idParent span ID for building trace trees (optional)
nameoperation_nameSpan name describing the operation
kindspan_kindMapped from numeric kind value (see table below)
status.codespan_statusMapped from numeric status code (see table below)
status.messagespan_status_messageOptional status description message
startTimeUnixNanotimestampSpan start time converted to ISO 8601
endTimeUnixNano - startTimeUnixNanoduration_msCalculated in milliseconds from start and end times
resource service.nameservice_nameFrom resource attribute service.name
http.method / http.request.methodhttp_methodExtracted from http.method or http.request.method span attribute
http.url / url.fullhttp_urlExtracted from http.url or url.full span attribute
http.status_codehttp_status_codeExtracted from http.status_code span attribute

Spans with status code 2 (error) are stored with level 'error'. All other spans are stored with level 'info'. Error spans also include the error_message field extracted from the status message or exception.message attribute.

Span Kind Values

Numeric ValueString Value
0unspecified
1internal
2server
3client
4producer
5consumer

Span Status Values

Numeric ValueString ValueLogPulse Level
0unsetinfo
1okinfo
2errorerror
Note: Spans with status code 2 (error) are automatically flagged and stored with level 'error' for easy filtering in LogPulse.

Kubernetes Metadata

When OTLP data includes Kubernetes resource attributes (following the OpenTelemetry semantic conventions), LogPulse automatically extracts them into dedicated columns for efficient filtering and namespace-based RBAC.

OTLP Resource AttributeLogPulse FieldDescription
k8s.cluster.nameclusterKubernetes cluster name
k8s.namespace.namenamespaceKubernetes namespace (used for RBAC filtering)
k8s.pod.namepodPod name
k8s.container.namecontainerContainer name within the pod
k8s.node.namenodeNode name (also used as the host field)
k8s.pod.labels.*labelsPod labels stored as key-value map
k8s.pod.annotation.*annotationsPod annotations stored as key-value map
Tip: Kubernetes attributes are stored as dedicated ClickHouse columns with optimized indexing. Use LPQL queries like namespace="production" or cluster="us-east-1" for fast filtering across millions of logs.

Attribute Value Types

OTLP attributes support multiple value types. LogPulse extracts and converts scalar types to strings for storage and searching. Complex types (arrays and key-value lists) are currently not extracted.

OTLP TypeExampleLogPulse Storage
stringValue"hello"Stored as-is
intValue42 or "42"Converted to string
doubleValue3.14Converted to string
boolValuetrueConverted to string ("true"/"false")
arrayValue[1, 2, 3]Not extracted (skipped)
kvlistValue{key: value}Not extracted (skipped)

Rate Limits & Quotas

OTLP endpoints share the same rate limits and quota system as the REST API. Limits are applied globally across all organizations.

EndpointLimitWindow
POST /v1/logs10,000Per minute
POST /v1/traces10,000Per minute

Daily Ingestion Quotas

Each organization has a daily data ingestion quota based on their plan. The quota covers all ingestion methods (REST API, OTLP, Vector). Ingestion is blocked at 125% of the daily limit.

PlanDaily Limit
Free1 GB/day
Starter1 GB/day
Pro10 GB/day
Business50 GB/day
Warning: When your quota reaches 80%, a warning notification is created. At 125% of the daily limit, all new ingestion is blocked until the next day (midnight UTC reset). Monitor your usage in the LogPulse dashboard.

Error Handling

The OTLP endpoints return standard HTTP status codes. Successful requests return an empty JSON body per the OTLP specification.

Status CodeError CodeMeaningAction
200Success: data acceptedNo action needed. Empty JSON body returned.
400INVALID_OTLP_FORMATInvalid OTLP payload formatVerify your payload matches the ExportLogsServiceRequest or ExportTraceServiceRequest schema.
401UNAUTHORIZEDMissing or invalid API keyCheck the Authorization header contains a valid Bearer token.
401API_KEY_REVOKEDAPI key has been revokedCreate a new API key in the LogPulse dashboard.
401API_KEY_EXPIREDAPI key has expiredRenew or create a new API key in the dashboard.
429QUOTA_EXCEEDEDDaily quota exceededWait until midnight UTC for quota reset, or upgrade your plan.
503STORAGE_NOT_CONFIGUREDStorage backend not availableRetry later. Contact support if the issue persists.
Note: Sending a request with an empty logs or traces array returns 200 OK (no-op). This is normal behavior per the OTLP specification.

Examples

Below are configuration examples for common setups. Replace YOUR_API_KEY with a valid API key from the LogPulse dashboard.

OpenTelemetry Collector

The OpenTelemetry Collector is the recommended way to send OTLP data to LogPulse. It acts as a local aggregator that batches, compresses, and forwards telemetry data.

otel-collector-config.yaml
receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317
      http:
        endpoint: 0.0.0.0:4318

exporters:
  # LogPulse accepts OTLP/HTTP with JSON payloads.
  # The otlphttp exporter appends /v1/logs and /v1/traces automatically
  # to the base endpoint. You can also set logs_endpoint / traces_endpoint
  # explicitly for clarity.
  otlphttp/logpulse-logs:
    endpoint: https://api.logpulse.io
    logs_endpoint: https://api.logpulse.io/v1/logs
    headers:
      Authorization: "Bearer YOUR_API_KEY"
    compression: gzip

  otlphttp/logpulse-traces:
    endpoint: https://api.logpulse.io
    traces_endpoint: https://api.logpulse.io/v1/traces
    headers:
      Authorization: "Bearer YOUR_API_KEY"
    compression: gzip

service:
  pipelines:
    logs:
      receivers: [otlp]
      exporters: [otlphttp/logpulse-logs]
    traces:
      receivers: [otlp]
      exporters: [otlphttp/logpulse-traces]
Tip: Use the OpenTelemetry Collector as a DaemonSet in Kubernetes for optimal performance. See the Kubernetes integration docs for a complete Helm chart setup.

OTel SDK (Logs)

Send logs directly from your application using the OpenTelemetry SDK. This example uses the Python SDK with the OTLP HTTP log exporter.

Python: OpenTelemetry SDK (Logs)
from opentelemetry.sdk._logs import LoggerProvider, LoggingHandler
from opentelemetry.sdk._logs.export import BatchLogRecordProcessor
from opentelemetry.exporter.otlp.proto.http._log_exporter import OTLPLogExporter
import logging

# Configure the OTLP exporter
exporter = OTLPLogExporter(
    endpoint="https://api.logpulse.io/v1/logs",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
)

# Set up the logger provider
logger_provider = LoggerProvider()
logger_provider.add_log_record_processor(
    BatchLogRecordProcessor(exporter)
)

# Attach to Python logging
handler = LoggingHandler(
    level=logging.DEBUG,
    logger_provider=logger_provider,
)
logging.getLogger().addHandler(handler)

# Use standard Python logging
logger = logging.getLogger("my-service")
logger.info("User signed up", extra={"user_id": "usr_123"})

OTel SDK (Traces)

Instrument your application with OpenTelemetry to automatically capture traces. This example uses the Node.js SDK with auto-instrumentation.

Node.js: OpenTelemetry SDK (Traces)
const { NodeSDK } = require('@opentelemetry/sdk-node');
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http');
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');

const sdk = new NodeSDK({
  traceExporter: new OTLPTraceExporter({
    url: 'https://api.logpulse.io/v1/traces',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY',
    },
  }),
  instrumentations: [getNodeAutoInstrumentations()],
  serviceName: 'my-node-service',
});

sdk.start();

// Your application code, spans are automatically created
// for HTTP requests, database calls, etc.

cURL (Logs)

cURL: Send OTLP logs
curl -X POST https://api.logpulse.io/v1/logs \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{
    "resourceLogs": [{
      "resource": {
        "attributes": [
          { "key": "service.name", "value": { "stringValue": "my-service" } },
          { "key": "k8s.namespace.name", "value": { "stringValue": "production" } }
        ]
      },
      "scopeLogs": [{
        "scope": { "name": "my-library", "version": "1.0.0" },
        "logRecords": [{
          "timeUnixNano": "1711018800000000000",
          "severityNumber": 9,
          "severityText": "INFO",
          "body": { "stringValue": "Order processed successfully" },
          "attributes": [
            { "key": "order_id", "value": { "stringValue": "ord_abc123" } },
            { "key": "amount", "value": { "doubleValue": 49.99 } }
          ]
        }]
      }]
    }]
  }'

cURL (Traces)

cURL: Send OTLP traces
curl -X POST https://api.logpulse.io/v1/traces \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{
    "resourceSpans": [{
      "resource": {
        "attributes": [
          { "key": "service.name", "value": { "stringValue": "api-gateway" } }
        ]
      },
      "scopeSpans": [{
        "scope": { "name": "express" },
        "spans": [{
          "traceId": "5b8efff798038103d269b633813fc60c",
          "spanId": "eee19b7ec3c1b174",
          "name": "GET /api/users",
          "kind": 2,
          "startTimeUnixNano": "1711018800000000000",
          "endTimeUnixNano": "1711018800045000000",
          "attributes": [
            { "key": "http.method", "value": { "stringValue": "GET" } },
            { "key": "http.url", "value": { "stringValue": "/api/users" } },
            { "key": "http.status_code", "value": { "intValue": 200 } }
          ],
          "status": { "code": 1 }
        }]
      }]
    }]
  }'

We use cookies to analyze site traffic and improve your experience. No cookies are placed without your consent. Privacy Policy