全部产品
Search
文档中心

Simple Log Service:Impor data jejak dari aplikasi Golang ke Layanan Log Sederhana menggunakan OpenTelemetry SDK untuk Golang

更新时间:Jul 06, 2025

Topik ini menjelaskan cara mengimpor data jejak dari aplikasi Golang ke Layanan Log Sederhana menggunakan OpenTelemetry SDK untuk Golang.

Prasyarat

  • Sebuah instance jejak telah dibuat. Untuk informasi lebih lanjut, lihat Buat Instance Jejak.

  • Lingkungan pengembangan Golang telah disiapkan. Versi Golang adalah 1.13 atau yang lebih baru.

Prosedur

  1. Inisialisasi penyedia OpenTelemetry.

  2. Periksa apakah kondisi untuk mengimpor data dalam mode semi-otomatis terpenuhi.

    • Jika kondisi terpenuhi, Anda dapat mengimpor data jejak dalam mode semi-otomatis.

      Jika mode semi-otomatis tidak memenuhi kebutuhan Anda, Anda harus mengimpor data jejak secara manual.

    • Jika kondisi tidak terpenuhi, Anda dapat mengimpor data jejak dalam mode manual.

Langkah 1: Inisialisasi penyedia OpenTelemetry

Layanan Log Sederhana menawarkan penyedia yang memungkinkan Anda membangun dependensi dan mengunggah dependensi tersebut ke Layanan Log Sederhana. Penyedia ini membantu menyederhanakan penggunaan penyedia OpenTelemetry. Untuk informasi lebih lanjut, lihat opentelemetry-go-provider-sls.

Penting

Anda harus menginisialisasi penyedia OpenTelemetry sebelum membuat jejak dan mendaftarkan metrik.

Anda dapat menjalankan kode atau mengonfigurasi variabel lingkungan untuk menginisialisasi penyedia OpenTelemetry.

  • Jalankan kode untuk menginisialisasi penyedia OpenTelemetry.

    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. Tulis kode inisialisasi.

      Ganti variabel dalam kode berikut dengan nilai sebenarnya. Untuk informasi lebih lanjut tentang variabel, lihat 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}"))
          // Panggil fungsi panic(). Jika inisialisasi gagal, penyedia OpenTelemetry keluar. Anda juga dapat menggunakan metode penanganan kesalahan lainnya. 
          if err != nil {
              panic(err)
          }
          if err := provider.Start(slsConfig); err != nil {
              panic(err)
          }
          defer provider.Shutdown(slsConfig)
          
          // Tambahkan kode logika bisnis. 
          ...
      }

      Tabel 1. Variabel

      Variabel

      Deskripsi

      Contoh

      ${service}

      Nama layanan. Tentukan nilai berdasarkan kebutuhan bisnis Anda.

      payment

      ${service.namespace}

      Namespace tempat layanan berada.

      order

      ${version}

      Versi layanan. Kami merekomendasikan Anda menentukan versi dalam format va.b.c.

      v0.1.2

      ${endpoint}

      Titik akhir proyek Layanan Log Sederhana. Format: ${project}.${region-endpoint}:Port.

      • ${project}: nama proyek Layanan Log Sederhana.

      • ${region-endpoint}: titik akhir Layanan Log Sederhana untuk wilayah tempat proyek berada. Anda dapat mengakses Layanan Log Sederhana menggunakan titik akhir internal atau publik. Titik akhir internal dapat diakses melalui jaringan klasik atau virtual private cloud (VPC). Titik akhir publik dapat diakses melalui Internet. Untuk informasi lebih lanjut, lihat Titik Akhir.

      • Port: nomor port. Nilainya tetap 10010.

      Catatan
      • Jika Anda mengatur variabel menjadi stdout, data dicetak ke output standar. Dalam hal ini, baris kode adalah provider.WithTraceExporterEndpoint("stdout").

      • Jika Anda membiarkan variabel kosong, data jejak tidak akan diunggah ke Layanan Log Sederhana.

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

      ${project}

      Nama proyek Layanan Log Sederhana.

      test-project

      ${instance}

      ID instance jejak. Untuk informasi lebih lanjut, lihat Buat instance jejak.

      test-traces

      ${access-key-id}

      ID AccessKey akun Alibaba Cloud Anda.

      Kami merekomendasikan Anda menggunakan pasangan AccessKey dari pengguna RAM yang hanya memiliki izin tulis pada proyek Layanan Log Sederhana. Pasangan AccessKey terdiri dari ID AccessKey dan Rahasia AccessKey. Untuk informasi lebih lanjut tentang cara memberikan izin tulis pada proyek tertentu kepada pengguna RAM, lihat Gunakan kebijakan kustom untuk memberikan izin kepada pengguna RAM. Untuk informasi lebih lanjut tentang cara mendapatkan pasangan AccessKey, lihat Pasangan AccessKey.

      Tidak ada

      ${access-key-secret}

      Rahasia AccessKey akun Alibaba Cloud Anda.

      Kami merekomendasikan Anda menggunakan pasangan AccessKey dari pengguna RAM yang hanya memiliki izin tulis pada proyek Layanan Log Sederhana.

      Tidak ada

  • Konfigurasikan variabel lingkungan untuk menginisialisasi penyedia OpenTelemetry.

    Metode konfigurasi

    Variabel lingkungan

    Diperlukan

    Deskripsi

    Nilai default

    WithServiceName

    SLS_OTEL_SERVICE_NAME

    Ya

    Nama layanan. Tentukan nilai berdasarkan kebutuhan bisnis Anda.

    Tidak ada

    WithServiceNamespace

    SLS_OTEL_SERVICE-NAMESPACE

    Tidak

    Namespace tempat layanan berada.

    order

    WithServiceVersion

    SLS_OTEL_SERVICE_VERSION

    Ya

    Versi layanan. Kami merekomendasikan Anda menentukan versi dalam format va.b.c.

    v0.1.0

    WithSLSConfig

    SLS_OTEL_PROJECT, SLS_OTEL_INSTANCE_ID, SLS_OTEL_ACCESS_KEY_ID, dan SLS_OTEL_ACCESS_KEY_SECRET

    Tidak

    Informasi tentang sumber daya Layanan Log Sederhana. Informasi ini mencakup nama proyek, nama instance jejak, ID AccessKey akun yang hanya memiliki izin tulis pada proyek, dan Rahasia AccessKey akun tersebut. Untuk informasi lebih lanjut tentang cara memberikan izin tulis pada proyek tertentu kepada pengguna RAM, lihat Gunakan kebijakan kustom untuk memberikan izin kepada pengguna RAM. Untuk informasi lebih lanjut tentang cara mendapatkan pasangan AccessKey, lihat Pasangan AccessKey.

    Tidak ada

    WithTraceExporterEndpoint

    SLS_OTEL_TRACE_ENDPOINT

    Tidak

    Titik akhir proyek Layanan Log Sederhana. Format: ${project}.${region-endpoint}:Port.

    • ${project}: nama proyek Layanan Log Sederhana.

    • ${region-endpoint}: titik akhir Layanan Log Sederhana untuk wilayah tempat proyek berada. Anda dapat mengakses Layanan Log Sederhana menggunakan titik akhir internal atau publik. Titik akhir internal dapat diakses melalui jaringan klasik atau VPC. Titik akhir publik dapat diakses melalui Internet. Untuk informasi lebih lanjut, lihat Titik Akhir.

    • Port: nomor port. Nilainya tetap 10010.

    Catatan
    • Jika Anda mengatur variabel menjadi stdout, data dicetak ke output standar.

    • Jika Anda membiarkan variabel kosong, data jejak tidak akan diunggah ke Layanan Log Sederhana.

    stdout

    WithTraceExporterInsecure

    SLS_OTEL_TRACE_INSECURE

    Tidak

    Menentukan apakah data ditransfer menggunakan metode yang tidak aman. Nilai valid:

    • true

    • false

    Catatan

    Jika Anda ingin mentransfer data langsung ke Layanan Log Sederhana, Anda harus mengatur variabel menjadi false.

    false

    WithMetricExporterEndpoint

    SLS_OTEL_METRIC_ENDPOINT

    Tidak

    Titik akhir proyek Layanan Log Sederhana. Format: ${project}.${region-endpoint}:Port.

    • ${project}: nama proyek Layanan Log Sederhana.

    • ${region-endpoint}: titik akhir Layanan Log Sederhana untuk wilayah tempat proyek berada. Anda dapat mengakses Layanan Log Sederhana menggunakan titik akhir internal atau publik. Titik akhir internal dapat diakses melalui jaringan klasik atau VPC. Titik akhir publik dapat diakses melalui Internet. Untuk informasi lebih lanjut, lihat Titik Akhir.

    • Port: nomor port. Nilainya tetap 10010.

    Catatan
    • Jika Anda mengatur variabel menjadi stdout, data dicetak ke output standar.

    • Jika Anda membiarkan variabel kosong, data metrik tidak akan diunggah ke Layanan Log Sederhana.

    stdout

    WithMetricExporterInsecure

    SLS_OTEL_METRIC_INSECURE

    Tidak

    Menentukan apakah data ditransfer menggunakan metode yang tidak aman. Nilai valid:

    • true

    • false

    Catatan

    Jika Anda ingin mentransfer data langsung ke Layanan Log Sederhana, Anda harus mengatur variabel menjadi false.

    false

    WithResourceAttributes

    Tidak ada

    Tidak

    Informasi tag tambahan, seperti lingkungan dan zona.

    Tidak ada

    WithResource

    OTEL_RESOURCE_ATTRIBUTES

    Tidak

    Informasi tag tambahan, seperti lingkungan dan zona. Format: key1=value1,key2=value2.

    Tidak ada

    WithMetricReportingPeriod

    SLS_OTEL_METRIC_EXPORT_PERIOD

    Tidak

    Interval pelaporan data metrik. Kami merekomendasikan Anda mengatur interval antara 15s hingga 60s.

    30s

    WithErrorHandler

    Tidak ada

    Tidak

    Fungsi penanganan kesalahan. Jika terjadi kesalahan internal SDK, sistem memanggil fungsi ini. Fungsi ini setara dengan fungsi WithErrorHandlerFunc.

    Tidak ada

    WithErrorHandlerFunc

    Tidak ada

    Tidak

    Fungsi penanganan kesalahan.

    Tidak ada

    Tidak ada

    SLS_OTEL_ATTRIBUTES_ENV_KEYS

    Tidak

    Informasi tag tambahan, seperti lingkungan dan zona. Variabel ini mirip dengan OTEL_RESOURCE_ATTRIBUTES. Namun, nilai kunci atribut yang didefinisikan dalam variabel SLS_OTEL_ATTRIBUTES_ENV_KEYS dibaca dari variabel lingkungan lainnya.

    SLS_OTEL_ATTRIBUTES_ENV_KEYS umumnya digunakan dalam kluster Kubernetes untuk memasukkan beberapa nilai template ke variabel lingkungan yang ditentukan. Format: env-key-1|env-key-2|env-key-3.

    Tidak ada

Langkah 2: Impor data

  • Mode Semi-Otomatis: Direkomendasikan

    OpenTelemetry menyediakan solusi instrumentasi otomatis untuk berbagai pustaka dasar. Jika bisnis Anda bergantung pada pustaka-pustaka ini, Anda dapat menggunakan solusi instrumentasi otomatis untuk mengimpor data. Untuk informasi lebih lanjut tentang pustaka dasar, lihat Instrumentasi.

    • Gunakan Framework .NET atau HTTP untuk Mengimpor Data

      Kode contoh berikut dibuat berdasarkan go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.37.0. Untuk informasi lebih lanjut, lihat otel-http-example.

      Ganti variabel dalam kode berikut dengan nilai sebenarnya. Untuk informasi lebih lanjut tentang variabel, lihat 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}"))
          // Panggil fungsi panic(). Jika inisialisasi gagal, penyedia OpenTelemetry keluar. Anda juga dapat menggunakan metode penanganan kesalahan lainnya. 
          if err != nil {
              panic(err)
          }
          if err := provider.Start(slsConfig); err != nil {
              panic(err)
          }
          defer provider.Shutdown(slsConfig)
      
          // Jika Anda ingin menganalisis data metrik dalam aplikasi, Anda dapat mendaftarkan metrik. 
          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 {
                  // Jika Anda ingin mencatat beberapa peristiwa, Anda dapat memperoleh rentang dalam konteks dan menambahkan peristiwa. 
                  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 solusi instrumentasi otomatis untuk otel net/http, Anda hanya perlu membungkus 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)
          }
      }
                                  
    • Gunakan Framework Gorilla Mux untuk Mengimpor Data

      Kode contoh berikut dibuat berdasarkan go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux v0.37.0. Antarmuka dapat berubah di versi selanjutnya. Untuk informasi lebih lanjut tentang kode contoh terbaru, lihat otel-mux-example.

      Ganti variabel dalam kode berikut dengan nilai sebenarnya. Untuk informasi lebih lanjut tentang variabel, lihat 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}"))
          // Panggil fungsi panic(). Jika inisialisasi gagal, penyedia OpenTelemetry keluar. Anda juga dapat menggunakan metode penanganan kesalahan lainnya. 
          if err != nil {
              panic(err)
          }
          if err := provider.Start(slsConfig); err != nil {
              panic(err)
          }
          defer provider.Shutdown(slsConfig)
      
          // Jika Anda ingin menganalisis data metrik dalam aplikasi, Anda dapat mendaftarkan metrik. 
          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"
          }
          // Jika Anda ingin mencatat beberapa peristiwa, Anda dapat memperoleh rentang dalam konteks dan menambahkan peristiwa. 
          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"
      }
                                  
  • Mode Manual

    Ganti variabel dalam kode berikut dengan nilai sebenarnya. Untuk informasi lebih lanjut tentang variabel, lihat 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"))
        // Panggil fungsi panic(). Jika inisialisasi gagal, penyedia OpenTelemetry keluar. Anda juga dapat menggunakan metode penanganan kesalahan 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 label. 
        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 rentang saat ini
    // Peroleh rentang saat ini. 
    func getSpan(ctx context.Context) {
        span := trace.SpanFromContext(ctx)
        fmt.Printf("current span: %v\n", span)
    }
    
    // contoh menambahkan atribut ke rentang
    // Tambahkan nilai atribut ke rentang. 
    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 peristiwa ke rentang
    // Tambahkan peristiwa ke rentang. 
    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 pengecualian
    // Catat hasil rentang dan informasi kesalahan. 
    func recordException(ctx context.Context) {
        span := trace.SpanFromContext(ctx)
        span.RecordError(errors.New("exception has occurred"))
        span.SetStatus(codes.Error, "internal error")
    }
    
    // contoh membuat rentang anak
    // Buat rentang 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)
    }
                        

Apa yang harus dilakukan selanjutnya