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
Inisialisasi penyedia OpenTelemetry.
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.
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.
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 )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.
CatatanJika 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.
CatatanJika 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
CatatanJika 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.
CatatanJika 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
CatatanJika 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) }