Kueri kontekstual menentukan sumber log, seperti mesin atau file tertentu, lalu mengambil log sebelum dan sesudah log tertentu dari sumber tersebut untuk memperoleh informasi kontekstual. Saat memproses volume log yang besar, Anda dapat menambahkan pengidentifikasi PackId untuk mengelompokkan log yang terkait. Dengan menggunakan PackId, Anda dapat melakukan kueri secara cepat dan lengkap terhadap kelompok log terkait guna menemukan konteks log secara efisien. Topik ini menjelaskan cara menambahkan PackId ke log.
Cara kerja
Server menggunakan mekanisme PackId untuk mengaitkan konteks log. Format PackId adalah Context Prefix-Log Group ID, misalnya 5FA51423DDB54FDA-1E3. PackId terdiri atas bagian-bagian berikut:
Context Prefix: Bilangan heksadesimal huruf besar. Contohnya,
5FA51423DDB54FDA. Log dengan context prefix yang sama termasuk dalam konteks log yang sama.Log Group ID: Bilangan heksadesimal huruf besar. Contohnya,
1E3. Dalam konteks log yang sama,Log Group IDbertambah secara berurutan. Misalnya,1E3dan1E4merupakan kelompok log yang berdekatan dalam konteks log yang sama.
Client menghasilkan PackId dan mengirimkannya ke server bersama permintaan penulisan log. Log yang memiliki context prefix yang sama dianggap berada dalam konteks log yang sama.
Hasilkan PackId secara otomatis
Log yang ditulis menggunakan SDK producer: Data log yang dikirim dari instans objek producer yang sama termasuk dalam konteks yang sama dan dapat langsung digunakan untuk kueri kontekstual. Misalnya, saat Anda menggunakan Aliyun Log Java Producer untuk menulis data log atau menulis log dengan C SDK, sistem secara otomatis menghasilkan dan menyertakan PackId sebagai identitas konteks.
Log yang dikumpulkan oleh Logtail: Untuk log yang dikumpulkan menggunakan Logtail, PackId dihasilkan dan disertakan secara otomatis. Log dari file log yang sama pada objek pengumpulan yang sama, seperti host atau Pod, termasuk dalam konteks yang sama dan dapat langsung digunakan untuk kueri kontekstual.
Hasilkan PackId secara manual dan unggah menggunakan API PutLogs
Deskripsi parameter
Anda dapat menggunakan API PutLogs untuk menulis log ke Simple Log Service. Setelah Anda menghasilkan PackId secara manual, letakkan di properti LogTags dari LogGroup dalam permintaan PutLogs. Atur Key menjadi __pack_id__. Kode berikut memberikan contoh:
{
"Topic": "my-topic",
"Source": "127.0.0.1",
"LogTags": [
{
"Key": "__pack_id__",
"Value": "5FA51423DDB54FDA-1"
},
{
"Key": "my_other_tag_key",
"Value": "my_other_tag_value"
}
],
"Logs": [
{
"Time": 1728961415,
"Contents": [
{
"Key": "hello",
"Value": "world"
}
]
}
]
}Kode contoh
Contoh Java
Tambahkan dependensi berikut ke file pom.xml.
<dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>27.0.1-jre</version> </dependency> <dependency> <groupId>com.aliyun.openservices</groupId> <artifactId>aliyun-log</artifactId> <version>0.6.111</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>2.0.12</version> </dependency>Gunakan kode berikut untuk menghasilkan PackId secara manual dan mengunggahnya menggunakan API PutLogs. Ganti parameter
project,logstore,endpoint,accessKeyId, danaccessKeySecretsesuai kebutuhan.package org.example; import com.aliyun.openservices.log.Client; import com.aliyun.openservices.log.common.LogItem; import com.aliyun.openservices.log.common.TagContent; import com.aliyun.openservices.log.exception.LogException; import com.aliyun.openservices.log.request.PutLogsRequest; import com.google.common.base.Charsets; import com.google.common.hash.Hashing; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.lang.management.ManagementFactory; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.SocketException; import java.util.ArrayList; import java.util.Arrays; import java.util.Enumeration; import java.util.List; import java.util.concurrent.atomic.AtomicLong; public class Main { private static final String TAG_PACK_ID = "__pack_id__"; private static final int TOKEN_LEN = 4; public static void main(String[] args) throws LogException { System.out.println("Hello world!"); // Gunakan PackIdGenerator yang sama untuk konteks yang sama. PackIdGenerator generator1 = new PackIdGenerator(); System.out.println(generator1.generateNewPackId()); System.out.println(generator1.generateNewPackId()); System.out.println(generator1.generateNewPackId()); // Gunakan PackIdGenerator yang berbeda untuk konteks yang berbeda. PackIdGenerator generator2 = new PackIdGenerator(); System.out.println(generator2.generateNewPackId()); System.out.println(generator2.generateNewPackId()); // Konfigurasi untuk log. String project = "project"; String logstore = "logstore"; String topic = "topic"; String source = "127.0.0.1"; Client client = new Client("endpoint", "accessKeyId", "accessKeySecret"); List<LogItem> logs = new ArrayList<>(); LogItem log = new LogItem(); log.PushBack("hello", "world"); logs.add(log); // Kirim permintaan log. PutLogsRequest req = new PutLogsRequest(project, logstore, topic, source, logs); // Masukkan pack ID ke daftar tag. req.SetTags(Arrays.asList(new TagContent(TAG_PACK_ID, generator1.generateNewPackId()))); client.PutLogs(req); // Kirim permintaan log. PutLogsRequest req2 = new PutLogsRequest(project, logstore, topic, source, logs); req.SetTags(Arrays.asList(new TagContent(TAG_PACK_ID, generator1.generateNewPackId()))); client.PutLogs(req2); } public static class NetworkUtils { private NetworkUtils() { } public static boolean isIpAddress(final String ipAddress) { if (ipAddress == null || ipAddress.isEmpty()) { return false; } try { final String[] tokens = ipAddress.split("\\."); if (tokens.length != TOKEN_LEN) { return false; } for (String token : tokens) { int i = Integer.parseInt(token); if (i < 0 || i > 255) { return false; } } return true; } catch (Exception ex) { return false; } } public static String getLocalMachineIp() { try { Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces(); while (networkInterfaces.hasMoreElements()) { NetworkInterface ni = networkInterfaces.nextElement(); if (!ni.isUp()) { continue; } Enumeration<InetAddress> addresses = ni.getInetAddresses(); while (addresses.hasMoreElements()) { final InetAddress address = addresses.nextElement(); if (!address.isLinkLocalAddress() && address.getHostAddress() != null) { String ipAddress = address.getHostAddress(); if ("127.0.0.1".equals(ipAddress)) { continue; } if (isIpAddress(ipAddress)) { return ipAddress; } } } } } catch (SocketException ex) { // abaikan } return null; } } public static class PackIdGenerator { private static final Logger LOGGER = LoggerFactory.getLogger(PackIdGenerator.class); private static final AtomicLong GENERATORID = new AtomicLong(0); private final String packIdPrefix; private final AtomicLong batchId = new AtomicLong(0); public PackIdGenerator() { packIdPrefix = generatePackIdPrefix(GENERATORID.getAndIncrement()).toUpperCase() + "-"; } public String generateNewPackId() { return packIdPrefix + Long.toHexString(batchId.getAndIncrement()).toUpperCase(); } private String generatePackIdPrefix(Long instanceId) { String ip = NetworkUtils.getLocalMachineIp(); if (ip == null) { LOGGER.warn("Gagal mendapatkan IP mesin lokal, atur IP ke 127.0.0.1"); ip = "127.0.0.1"; } String name = ManagementFactory.getRuntimeMXBean().getName(); String input = ip + "-" + name + "-" + instanceId; return Hashing.farmHashFingerprint64().hashString(input, Charsets.US_ASCII).toString(); } } }
Contoh Go
Jalankan perintah berikut di command line untuk menginstal SDK Go dan paket dependensi protobuf.
go get -u github.com/aliyun/aliyun-log-go-sdk go get google.golang.org/protobufGunakan kode berikut untuk menghasilkan PackId secara manual dan mengunggahnya menggunakan API PutLogs. Ganti parameter
project,logstore,endpoint,accessKeyId, danaccessKeySecretsesuai kebutuhan.package main import ( "crypto/md5" "fmt" "os" "sync/atomic" "time" sls "github.com/aliyun/aliyun-log-go-sdk" "google.golang.org/protobuf/proto" ) func main() { // Gunakan PackIdGenerator yang sama untuk konteks yang sama. g1 := NewPackIdGenerator() fmt.Println(g1.Generate()) fmt.Println(g1.Generate()) fmt.Println(g1.Generate()) // Gunakan PackIdGenerator yang berbeda untuk konteks yang berbeda. g2 := NewPackIdGenerator() fmt.Println(g2.Generate()) fmt.Println(g2.Generate()) // Konfigurasi untuk log. project := "project" logstore := "logStore" topic := "topic" source := "source" client := sls.CreateNormalInterface("endpoint", "accessKeyId", "accessKeySecret", "") logs := []*sls.Log{ { Time: proto.Uint32(uint32(time.Now().Unix())), Contents: []*sls.LogContent{ { Key: proto.String("hello"), Value: proto.String("world"), }, { Key: proto.String("hi"), Value: proto.String("world"), }, }, }, } // Gunakan API PostLogStoreLogsV2 untuk menulis log. err := client.PostLogStoreLogsV2(project, logstore, &sls.PostLogStoreLogsRequest{ LogGroup: &sls.LogGroup{ Topic: &topic, Source: &source, Logs: logs, LogTags: []*sls.LogTag{ { Key: proto.String("__pack_id__"), // Tambahkan pack ID ke daftar tag. Value: proto.String(g1.Generate()), }, }, }, }) if err != nil { panic(err) } // Gunakan API PutLogs untuk menulis log. g1.Generate() menghasilkan pack ID baru. err = client.PutLogs(project, logstore, &sls.LogGroup{ Topic: &topic, Source: &source, Logs: logs, LogTags: []*sls.LogTag{ { Key: proto.String("__pack_id__"), // Tambahkan pack ID ke daftar tag. Value: proto.String(g1.Generate()), }, }, }) if err != nil { panic(err) } } type PackIdGenerator struct { prefix string id atomic.Uint64 } func NewPackIdGenerator() *PackIdGenerator { return &PackIdGenerator{ prefix: generatePackIDPrefix(), id: atomic.Uint64{}, } } func (g *PackIdGenerator) Generate() string { return fmt.Sprintf("%s-%X", g.prefix, g.id.Add(1)) } // Buat konteks berdasarkan (hostname, pid, waktu). func generatePackIDPrefix() string { m := md5.New() m.Write([]byte(time.Now().String())) hostName, _ := os.Hostname() m.Write([]byte(hostName)) m.Write([]byte(fmt.Sprintf("%v", os.Getpid()))) return fmt.Sprintf("%X", m.Sum(nil)) }
Lihat informasi konteks log
Pada halaman Proyek target, klik LogStore target. Di tab , temukan log target dan klik ikon
.CatatanSaat log dikirim menggunakan API PutLogs, Simple Log Service mengelompokkan log yang memiliki context prefix PackId yang sama ke dalam satu konteks log. Anda dapat mengklik fitur Context View untuk melihat informasi kontekstual log tertentu. Fitur ini akan menampilkan semua kelompok log yang memiliki context prefix yang sama dan menyorot log target.

Gulir ke atas atau bawah untuk melihat konteks log yang ditentukan.

Referensi
Untuk mempelajari cara melihat konteks log di Konsol, lihat Kueri kontekstual.
Untuk mempelajari cara menulis data log ke Simple Log Service menggunakan SDK atau API, lihat Gunakan Aliyun Log Java Producer untuk menulis data log, C SDK, atau PutLogs.