Closed ddatsh closed 3 weeks ago
You should try using a custom HTTP client in Go to send logs directly to O2, we can control the format and headers of the HTTP requests. This allows us to send logs in pure JSON format, which OpenObserve’s ingestion API requires. Refer to https://pkg.go.dev/net/http to create and send HTTP requests using the http.NewRequest
and http.Client.Do
methods.
It should look somewhat like this although you have to Define a LogEntry
struct for JSON log data and marshal it using json.Marshal
req, err := http.NewRequestWithContext(ctx, "POST", "http://127.0.0.1:5080/api/default/default/_json", bytes.NewBuffer(logData))
if err != nil {
fmt.Println("Error creating request:", err)
return
}
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
fmt.Println("Error sending request:", err)
return
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
fmt.Printf("Failed to send log entry, status code: %d\n", resp.StatusCode)
} else {
fmt.Println("Log entry sent successfully")
}
solved /api/default/v1/logs
package main
import (
"context"
"encoding/base64"
"fmt"
"go.opentelemetry.io/contrib/bridges/otelslog"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
"go.opentelemetry.io/otel/log/global"
"go.opentelemetry.io/otel/propagation"
"go.opentelemetry.io/otel/sdk/log"
"go.opentelemetry.io/otel/sdk/resource"
tracesdk "go.opentelemetry.io/otel/sdk/trace"
semconv "go.opentelemetry.io/otel/semconv/v1.26.0"
)
func main() {
ctx := context.Background()
auth := "Basic " + base64.StdEncoding.EncodeToString([]byte("i@ddatsh.com:admin"))
authHeader := map[string]string{
"Authorization": auth,
"stream-name": "default",
}
logExporter, _ := otlploghttp.New(ctx,
otlploghttp.WithEndpoint("127.0.0.1:5080"),
otlploghttp.WithURLPath("/api/default/v1/logs"),
otlploghttp.WithInsecure(),
otlploghttp.WithHeaders(authHeader),
otlploghttp.WithCompression(1),
)
// Create a logger provider.
// You can pass this instance directly when creating a log bridge.
lp := log.NewLoggerProvider(
log.WithProcessor(log.NewBatchProcessor(logExporter)),
)
// Handle shutdown properly so that nothing leaks.
defer func() {
err := lp.Shutdown(context.Background())
if err != nil {
fmt.Println(err)
}
}()
global.SetLoggerProvider(lp)
traceClientHttp := otlptracehttp.NewClient(
otlptracehttp.WithEndpointURL("http://127.0.0.1:5080/api/default/v1/traces"),
otlptracehttp.WithInsecure(), otlptracehttp.WithHeaders(authHeader))
otlptracehttp.WithCompression(1)
exporter, _ := otlptrace.New(ctx, traceClientHttp)
tp := tracesdk.NewTracerProvider(
// Always be sure to batch in production.
tracesdk.WithBatcher(exporter),
// Record information about this application in a Resource.
tracesdk.WithResource(resource.NewWithAttributes(
semconv.SchemaURL,
semconv.ServiceNameKey.String("api"),
attribute.String("environment", "prod"))),
)
defer func() {
err := tp.Shutdown(context.Background())
if err != nil {
fmt.Println(err)
}
}()
otel.SetTracerProvider(tp)
otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}))
ctx, span := otel.GetTracerProvider().Tracer("").Start(ctx, "test")
span.AddEvent("test event")
defer span.End()
logger := otelslog.NewLogger("api", otelslog.WithLoggerProvider(lp))
logger.InfoContext(ctx, "shutdown service")
}
btw trace to view log, settings organization parameters > trace id/span id field name from traceId/spanId > trace_id/span_id
I want to send the log directly to OpenObserve log, use such as slog
127.0.0.1:5080/api/default/default/_json accept pure json format
go.opentelemetry.io\otel\exporters\otlp\otlplog\otlploghttp@v0.6.0\client.go use application/x-protobuf format