全部产品
Search
文档中心

:Ingest data jejak Golang menggunakan OpenTelemetry

更新时间:Dec 31, 2025

Topik ini menjelaskan cara menggunakan kit pengembangan perangkat lunak (SDK) OpenTelemetry untuk Golang guna mengingest data jejak dari aplikasi Golang ke Simple Log Service.

Catatan

Simple Log Service menyediakan probe komersial berpemilik untuk bahasa Go. Probe ini menawarkan instrumentasi non-intrusif, fitur tambahan, dan stabilitas yang lebih baik. Untuk informasi selengkapnya, lihat Mulai memantau aplikasi Go.

Prasyarat

  • Lingkungan pengembangan Golang versi 1.13 atau yang lebih baru telah diinstal.

Alur ingest

  1. Inisialisasi penyedia OpenTelemetry.

  2. Tentukan apakah kondisi untuk ingest semi-otomatis terpenuhi.

    • Jika kondisi terpenuhi, gunakan metode semi-otomatis untuk mengingest data jejak.

      Untuk skenario yang tidak didukung oleh metode semi-otomatis, gunakan metode manual.

    • Jika kondisi tidak terpenuhi, gunakan metode manual untuk mengingest data jejak.

Langkah 1: Inisialisasi penyedia OpenTelemetry

Untuk menyederhanakan penggunaan penyedia OpenTelemetry, Simple Log Service menyediakan SLS Provider, yang membantu Anda membangun dependensi yang diperlukan dan mengunggahnya ke Simple Log Service dengan cepat.

Penting

Inisialisasi penyedia OpenTelemetry sebelum membuat jejak atau mendaftarkan metrik.

Anda dapat menginisialisasi penyedia OpenTelemetry dengan menjalankan kode atau mengonfigurasi variabel lingkungan:

  • Inisialisasi dengan menjalankan kode.

    1. Tambahkan dependensi.

      module opentelemetry-golang-sample
      
      go 1.13
      
      require (
          github.com/aliyun-sls/opentelemetry-go-provider-sls v0.10.0
          go.opentelemetry.io/otel v1.16.0
          go.opentelemetry.io/otel/metric v1.16.0
          go.opentelemetry.io/otel/trace v1.16.0
      )
    2. Konfigurasikan kode inisialisasi.

      Ganti variabel dalam kode berikut sesuai kebutuhan Anda. Untuk deskripsi variabel, lihat Deskripsi variabel.

      package main
      
      import (
          "github.com/aliyun-sls/opentelemetry-go-provider-sls/provider"
      )
      
      func main() {
      
          slsConfig, err := provider.NewConfig(provider.WithServiceName("${service}"),
              provider.WithServiceNamespace("${service.namespace}"),
              provider.WithServiceVersion("${version}"),
              provider.WithTraceExporterEndpoint("${endpoint}"),
              provider.WithMetricExporterEndpoint("${endpoint}"),
              provider.WithSLSConfig("${project}", "${instance}", "${access-key-id}", "${access-key-secret}"))
          // Gunakan panic() untuk keluar dari program jika inisialisasi gagal. Anda juga dapat menggunakan metode penanganan error lainnya.
          if err != nil {
              panic(err)
          }
          if err := provider.Start(slsConfig); err != nil {
              panic(err)
          }
          defer provider.Shutdown(slsConfig)
          
          // Tambahkan kode logika bisnis Anda.
          ...
      }

      Tabel 1. Deskripsi variabel

      Variabel

      Deskripsi

      Contoh

      ${service}

      Nama layanan. Atur parameter ini berdasarkan skenario Anda.

      payment

      ${service.namespace}

      Namespace tempat layanan tersebut berada.

      order

      ${version}

      Nomor versi layanan. Gunakan format va.b.c.

      v0.1.2

      ${endpoint}

      Titik akhir proyek Simple Log Service. Formatnya adalah ${project}.${region-endpoint}:Port. Parameter dijelaskan sebagai berikut:

      • ${project}: Nama proyek Simple Log Service.

      • ${region-endpoint}: Titik akhir wilayah tempat proyek Simple Log Service berada. Titik akhir jaringan publik, jaringan klasik, dan VPC didukung. Untuk informasi selengkapnya, lihat Endpoints.

      • Port: Port jaringan. Nilainya tetap 10010.

      Catatan
      • Jika Anda mengatur parameter ini ke stdout, misalnya, provider.WithTraceExporterEndpoint("stdout"), data akan dicetak ke output standar.

      • Jika Anda membiarkan parameter ini kosong, data jejak tidak diunggah ke Simple Log Service.

      test-project.cn-hangzhou.log.aliyuncs.com:10010

      ${project}

      Nama proyek Simple Log Service.

      test-project

      ${instance}

      ID instans Trace. Untuk informasi selengkapnya, lihat Buat instans Trace.

      test-traces

      ${access-key-id}

      ID AccessKey Akun Alibaba Cloud Anda.

      Gunakan pasangan Kunci Akses (ID AccessKey dan Rahasia AccessKey) dari Pengguna Resource Access Management (RAM) yang hanya memiliki izin menulis pada proyek Simple Log Service. Untuk informasi selengkapnya tentang cara memberikan izin kepada Pengguna RAM untuk menulis data ke proyek tertentu, lihat Otorisasi. Untuk informasi selengkapnya tentang cara mendapatkan pasangan Kunci Akses, lihat Pasangan Kunci Akses.

      None

      ${access-key-secret}

      Rahasia AccessKey Akun Alibaba Cloud Anda.

      Gunakan pasangan Kunci Akses dari Pengguna RAM yang hanya memiliki izin menulis pada proyek Simple Log Service.

      None

  • Inisialisasi dengan mengonfigurasi variabel lingkungan.

    Metode konfigurasi

    Variabel lingkungan

    Wajib

    Deskripsi

    Nilai default

    WithServiceName

    SLS_OTEL_SERVICE_NAME

    Ya

    Nama layanan. Atur parameter ini berdasarkan skenario Anda.

    None

    WithServiceNamespace

    SLS_OTEL_SERVICE-NAMESPACE

    Tidak

    Namespace tempat layanan tersebut berada.

    order

    WithServiceVersion

    SLS_OTEL_SERVICE_VERSION

    Ya

    Nomor versi layanan. Gunakan format va.b.c.

    v0.1.0

    WithSLSConfig

    SLS_OTEL_PROJECT, SLS_OTEL_INSTANCE_ID, SLS_OTEL_ACCESS_KEY_ID, SLS_OTEL_ACCESS_KEY_SECRET

    Tidak

    Informasi resource Simple Log Service, termasuk nama proyek, nama instans Trace, serta ID AccessKey dan Rahasia AccessKey pengguna yang hanya memiliki izin menulis pada proyek tersebut. Untuk informasi selengkapnya tentang cara memberikan izin kepada Pengguna RAM untuk menulis data ke proyek tertentu, lihat Otorisasi. Untuk informasi selengkapnya tentang cara mendapatkan pasangan Kunci Akses, lihat Pasangan Kunci Akses.

    None

    WithTraceExporterEndpoint

    SLS_OTEL_TRACE_ENDPOINT

    Tidak

    Titik akhir proyek Simple Log Service. Formatnya adalah ${project}.${region-endpoint}:Port. Parameter dijelaskan sebagai berikut:

    • ${project}: Nama proyek Simple Log Service.

    • ${region-endpoint}: Titik akhir wilayah tempat proyek Simple Log Service berada. Akses jaringan internal dan publik didukung. Untuk informasi selengkapnya, lihat Endpoints.

    • Port: Port jaringan. Nilainya tetap 10010.

    Catatan
    • Jika Anda mengatur parameter ini ke stdout, data akan dicetak ke output standar.

    • Jika Anda membiarkan parameter ini kosong, data jejak tidak diunggah ke Simple Log Service.

    stdout

    WithTraceExporterInsecure

    SLS_OTEL_TRACE_INSECURE

    Tidak

    Menentukan apakah akan menggunakan metode transmisi yang tidak aman.

    • true: Gunakan metode transmisi yang tidak aman.

    • false: Gunakan metode transmisi yang aman.

    Catatan

    Jika mengirim data langsung ke Simple Log Service, atur parameter ini ke false.

    false

    WithMetricExporterEndpoint

    SLS_OTEL_METRIC_ENDPOINT

    Tidak

    Titik akhir proyek Simple Log Service. Formatnya adalah ${project}.${region-endpoint}:Port. Parameter dijelaskan sebagai berikut:

    • ${project}: Nama proyek Simple Log Service.

    • ${region-endpoint}: Titik akhir wilayah tempat proyek Simple Log Service berada. Akses jaringan internal dan publik didukung. Untuk informasi selengkapnya, lihat Endpoints.

    • Port: Port jaringan. Nilainya tetap 10010.

    Catatan
    • Jika Anda mengatur parameter ini ke stdout, data akan dicetak ke output standar.

    • Jika Anda membiarkan parameter ini kosong, data metrik tidak diunggah ke Simple Log Service.

    stdout

    WithMetricExporterInsecure

    SLS_OTEL_METRIC_INSECURE

    Tidak

    Menentukan apakah akan menggunakan metode transmisi yang tidak aman.

    • true: Gunakan metode transmisi yang tidak aman.

    • false: Gunakan metode transmisi yang aman.

    Catatan

    Jika mengirim data langsung ke Simple Log Service, atur parameter ini ke false.

    false

    WithResourceAttributes

    None

    Tidak

    Konfigurasikan tag tambahan, seperti environment dan zona.

    None

    WithResource

    OTEL_RESOURCE_ATTRIBUTES

    Tidak

    Konfigurasikan tag tambahan, seperti environment dan zona. Formatnya adalah key1=value1,key2=value2.

    None

    WithMetricReportingPeriod

    SLS_OTEL_METRIC_EXPORT_PERIOD

    Tidak

    Interval ekspor metrik. Atur nilai antara 15s hingga 60s.

    30s

    WithErrorHandler

    None

    Tidak

    Fungsi penanganan error. Fungsi ini dipanggil ketika terjadi error internal di SDK. Efeknya sama dengan WithErrorHandlerFunc.

    None

    WithErrorHandlerFunc

    None

    Tidak

    Fungsi penanganan error.

    None

    None

    SLS_OTEL_ATTRIBUTES_ENV_KEYS

    Tidak

    Konfigurasikan tag tambahan, seperti environment dan zona. Ini mirip dengan OTEL_RESOURCE_ATTRIBUTES. Perbedaannya adalah untuk kunci atribut yang didefinisikan oleh SLS_OTEL_ATTRIBUTES_ENV_KEYS, nilai aktualnya dibaca dari variabel lingkungan yang sesuai.

    Ini sering digunakan dalam skenario Kubernetes untuk mengisi nilai templat ke variabel lingkungan tertentu. Formatnya adalah env-key-1|env-key-2|env-key-3.

    None

Langkah 2: Memasukkan data

  • (Direkomendasikan) Ingest semi-otomatis

    OpenTelemetry menyediakan instrumentasi otomatis untuk banyak library umum. Jika aplikasi Anda menggunakan library tersebut, Anda dapat menggunakan solusi instrumentasi otomatis yang sesuai untuk mengingest data. Untuk daftar library yang didukung, lihat Solusi instrumentasi otomatis Golang.

    • Ingest net/http

      Contoh berikut didasarkan pada go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.37.0. Untuk informasi selengkapnya, lihat otel-http-example.

      Ganti variabel dalam kode berikut sesuai kebutuhan Anda. Untuk deskripsi variabel, lihat Deskripsi variabel.

      package main
      
      import (
          "fmt"
          "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
          "go.opentelemetry.io/otel/attribute"
          "go.opentelemetry.io/otel/metric/global"
          "io"
          "net/http"
          "time"
      
          "github.com/aliyun-sls/opentelemetry-go-provider-sls/provider"
      
          "go.opentelemetry.io/otel/trace"
      )
      
      func main() {
      
          slsConfig, err := provider.NewConfig(provider.WithServiceName("${service}"),
              provider.WithServiceNamespace("${service.namespace}"),
              provider.WithServiceVersion("${version}"),
              provider.WithTraceExporterEndpoint("${endpoint}"),
              provider.WithMetricExporterEndpoint("${endpoint}"),
              provider.WithSLSConfig("${project}", "${instance}", "${access-key-id}", "${access-key-secret}"))
          // Gunakan panic() untuk keluar dari program jika inisialisasi gagal. Anda juga dapat menggunakan metode penanganan error lainnya.
          if err != nil {
              panic(err)
          }
          if err := provider.Start(slsConfig); err != nil {
              panic(err)
          }
          defer provider.Shutdown(slsConfig)
      
          // Untuk menganalisis data metrik di aplikasi Anda, Anda dapat mendaftarkan metrik yang relevan.
          labels := []attribute.KeyValue{
              attribute.String("label1", "value1"),
          }
          meter := global.Meter("aliyun.sls")
          sayDavidCount, _ := meter.Int64Counter("say_david_count")
      
          helloHandler := func(w http.ResponseWriter, req *http.Request) {
              if time.Now().Unix()%10 == 0 {
                  _, _ = io.WriteString(w, "Hello, world!\n")
              } else {
                  // Untuk mencatat event, Anda dapat mengambil Span dari Context dan menambahkan Event.
                  ctx := req.Context()
                  span := trace.SpanFromContext(ctx)
                  span.AddEvent("say : Hello, I am david", trace.WithAttributes(attribute.KeyValue{
                      Key:   "label-key-1",
                      Value: attribute.StringValue("label-value-1"),
                  }))
      
                  _, _ = io.WriteString(w, "Hello, I am david!\n")
                  sayDavidCount.Add(req.Context(), 1, labels...)
              }
          }
      
          // Untuk menggunakan injeksi otomatis otel net/http, cukup bungkus http.Handler dengan otelhttp.NewHandler.
          otelHandler := otelhttp.NewHandler(http.HandlerFunc(helloHandler), "Hello")
      
          http.Handle("/hello", otelHandler)
          fmt.Println("Now listen port 8080, you can visit 127.0.0.1:8080/hello .")
          err = http.ListenAndServe(":8080", nil)
          if err != nil {
              panic(err)
          }
      }
                                  
    • Ingest mux

      Contoh berikut didasarkan pada go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux v0.37.0. API dapat berubah di versi yang lebih baru. Untuk contoh terbaru, lihat otel-mux-example.

      Ganti variabel dalam kode berikut sesuai kebutuhan Anda. Untuk deskripsi variabel, lihat Deskripsi variabel.

      package main
      
      import (
          "context"
          "fmt"
          "go.opentelemetry.io/otel/attribute"
          "go.opentelemetry.io/otel/metric/global"
          "net/http"
      
          "github.com/aliyun-sls/opentelemetry-go-provider-sls/provider"
      
          "github.com/gorilla/mux"
          "go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux"
          "go.opentelemetry.io/otel/trace"
      )
      
      func main() {
      
          slsConfig, err := provider.NewConfig(provider.WithServiceName("${service}"),
              provider.WithServiceNamespace("${service.namespace}"),
              provider.WithServiceVersion("${version}"),
              provider.WithTraceExporterEndpoint("${endpoint}"),
              provider.WithMetricExporterEndpoint("${endpoint}"),
              provider.WithSLSConfig("${project}", "${instance}", "${access-key-id}", "${access-key-secret}"))
          // Gunakan panic() untuk keluar dari program jika inisialisasi gagal. Anda juga dapat menggunakan metode penanganan error lainnya.
          if err != nil {
              panic(err)
          }
          if err := provider.Start(slsConfig); err != nil {
              panic(err)
          }
          defer provider.Shutdown(slsConfig)
      
          // Untuk menganalisis data metrik di aplikasi Anda, Anda dapat mendaftarkan metrik yang relevan.
          labels := []attribute.KeyValue{
              attribute.String("label1", "value1"),
          }
          meter := global.Meter("aliyun.sls")
          callUsersCount, _ := meter.Int64Counter("call_users_count")
      
          r := mux.NewRouter()
          r.Use(otelmux.Middleware("my-server"))
          r.HandleFunc("/users/{id:[0-9]+}", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
              vars := mux.Vars(r)
              id := vars["id"]
              callUsersCount.Add(r.Context(), 1, labels...)
              name := getUser(r.Context(), id)
              reply := fmt.Sprintf("user %s (id %s)\n", name, id)
              _, _ = w.Write(([]byte)(reply))
          }))
          http.Handle("/", r)
          fmt.Println("Now listen port 8080, you can visit 127.0.0.1:8080/users/xxx .")
          _ = http.ListenAndServe(":8080", nil)
      }
      
      func getUser(ctx context.Context, id string) string {
          if id == "123" {
              return "otelmux tester"
          }
          // Untuk mencatat event, Anda dapat mengambil Span dari Context dan menambahkan Event.
          span := trace.SpanFromContext(ctx)
          span.AddEvent("unknown user id : "+id, trace.WithAttributes(attribute.KeyValue{
              Key:   "label-key-1",
              Value: attribute.StringValue("label-value-1"),
          }))
          return "unknown"
      }
                                  
  • Pemasukan Manual

    Ganti variabel dalam kode berikut sesuai kebutuhan Anda. Untuk deskripsi variabel, lihat Deskripsi variabel.

    // Copyright The AliyunSLS Authors
    //
    // Licensed under the Apache License, Version 2.0 (the "License");
    // you may not use this file except in compliance with the License.
    // You may obtain a copy of the License at
    //
    //     http://www.apache.org/licenses/LICENSE-2.0
    //
    // Unless required by applicable law or agreed to in writing, software
    // distributed under the License is distributed on an "AS IS" BASIS,
    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    // See the License for the specific language governing permissions and
    // limitations under the License.
    
    package main
    
    import (
        "context"
        "errors"
        "fmt"
        "go.opentelemetry.io/otel/attribute"
        "go.opentelemetry.io/otel/metric/global"
        "go.opentelemetry.io/otel/metric/instrument"
        "math/rand"
        "time"
    
        "github.com/aliyun-sls/opentelemetry-go-provider-sls/provider"
    
        "go.opentelemetry.io/otel"
        "go.opentelemetry.io/otel/codes"
        "go.opentelemetry.io/otel/trace"
    )
    
    func main() {
        slsConfig, err := provider.NewConfig(provider.WithServiceName("payment"),
            provider.WithServiceVersion("v0.1.0"),
            provider.WithTraceExporterEndpoint("stdout"),
            provider.WithMetricExporterEndpoint("stdout"),
            provider.WithSLSConfig("test-project", "test-otel", "access-key-id", "access-key-secret"))
        // Gunakan panic() untuk keluar dari program jika inisialisasi gagal. Anda juga dapat menggunakan metode penanganan error lainnya.
        if err != nil {
            panic(err)
        }
        if err := provider.Start(slsConfig); err != nil {
            panic(err)
        }
        defer provider.Shutdown(slsConfig)
    
        mockTrace()
        mockMetrics()
    }
    
    func mockMetrics() {
        // Tambahkan informasi tag.
        labels := []attribute.KeyValue{
            attribute.String("label1", "value1"),
        }
    
        meter := global.Meter("ex.com/basic")
    
        meter.Float64ObservableCounter("randval", instrument.WithFloat64Callback(func(ctx context.Context, observer instrument.Float64Observer) error {
            observer.Observe(rand.Float64(), labels...)
            return nil
        }))
    
        temperature, _ := meter.Float64Counter("temperature")
        interrupts, _ := meter.Int64Counter("interrupts")
    
        ctx := context.Background()
    
        for {
            temperature.Add(ctx, 100+10*rand.NormFloat64(), labels...)
            interrupts.Add(ctx, int64(rand.Intn(100)), labels...)
    
            time.Sleep(time.Second * time.Duration(rand.Intn(10)))
        }
    }
    
    func mockTrace() {
    
        tracer := otel.Tracer("ex.com/basic")
    
        ctx0 := context.Background()
    
        ctx1, finish1 := tracer.Start(ctx0, "foo")
        defer finish1.End()
    
        ctx2, finish2 := tracer.Start(ctx1, "bar")
        defer finish2.End()
    
        ctx3, finish3 := tracer.Start(ctx2, "baz")
        defer finish3.End()
    
        ctx := ctx3
        getSpan(ctx)
        addAttribute(ctx)
        addEvent(ctx)
        recordException(ctx)
        createChild(ctx, tracer)
    }
    
    // contoh mendapatkan span saat ini
    // Dapatkan Span saat ini.
    func getSpan(ctx context.Context) {
        span := trace.SpanFromContext(ctx)
        fmt.Printf("current span: %v\n", span)
    }
    
    // contoh menambahkan atribut ke span
    // Tambahkan atribut ke Span.
    func addAttribute(ctx context.Context) {
        span := trace.SpanFromContext(ctx)
        span.SetAttributes(attribute.KeyValue{
            Key:   "label-key-1",
            Value: attribute.StringValue("label-value-1")})
    }
    
    // contoh menambahkan event ke span
    // Tambahkan event ke Span.
    func addEvent(ctx context.Context) {
        span := trace.SpanFromContext(ctx)
        span.AddEvent("event1", trace.WithAttributes(
            attribute.String("event-attr1", "event-string1"),
            attribute.Int64("event-attr2", 10)))
    }
    
    // contoh mencatat exception
    // Catat hasil Span dan pesan error.
    func recordException(ctx context.Context) {
        span := trace.SpanFromContext(ctx)
        span.RecordError(errors.New("exception has occurred"))
        span.SetStatus(codes.Error, "internal error")
    }
    
    // contoh membuat child span
    // Buat Span anak.
    func createChild(ctx context.Context, tracer trace.Tracer) {
        // span := trace.SpanFromContext(ctx)
        _, childSpan := tracer.Start(ctx, "child")
        defer childSpan.End()
        fmt.Printf("child span: %v\n", childSpan)
    }
                        

Langkah selanjutnya