Kueri kontekstual memungkinkan Anda menentukan sumber log, seperti file pada mesin tertentu, lalu mengambil log yang mendahului dan mengikuti entri log tertentu untuk melihat konteksnya. Saat memproses volume log yang besar, Anda dapat mengelompokkan entri log terkait dengan menambahkan PackId. Penggunaan PackId memungkinkan Anda melakukan kueri cepat terhadap seluruh kelompok log terkait dan secara efisien menemukan konteks log tersebut. Topik ini menjelaskan cara menambahkan PackId ke log Anda.
Cara kerja
Server menggunakan mekanisme PackId untuk mengaitkan konteks log. Format PackId adalah awalan kontekstual-ID kelompok log, contohnya 5FA51423DDB54FDA-1E3. Rinciannya sebagai berikut:
-
Awalan kontekstual: Terdiri dari digit heksadesimal huruf kapital. Contohnya,
5FA51423DDB54FDA. Log dengan awalan kontekstual yang sama termasuk dalam konteks log yang sama. -
ID kelompok log: Terdiri dari digit heksadesimal huruf kapital. Contohnya,
1E3. Dalam konteks log yang sama,ID kelompok logbersifat inkremental. Misalnya,1E3dan1E4merepresentasikan kelompok log bersebelahan dalam konteks log yang sama.
Klien menghasilkan PackId dan mengirimkannya ke server sebagai bagian dari permintaan penulisan log. Log yang memiliki awalan kontekstual yang sama dianggap berada dalam konteks log yang sama.
Generasi PackId otomatis
-
Log yang ditulis menggunakan Producer SDK: Data log yang dikirim dari instans Producer yang sama termasuk dalam konteks yang sama dan dapat langsung digunakan untuk kueri kontekstual. Misalnya, saat Anda menulis log menggunakan Aliyun Log Java Producer atau C Producer SDK, sistem secara otomatis menghasilkan dan menyertakan
PackIdsebagai pengidentifikasi konteks. -
Log yang dikumpulkan menggunakan Logtail: Log yang dikumpulkan oleh Logtail secara otomatis menyertakan
PackId. Log dari file yang sama pada sumber pengumpulan yang sama, seperti host atau Pod, termasuk dalam konteks yang sama dan dapat langsung digunakan untuk kueri kontekstual.
Buat PackId secara manual dan unggah melalui PutLogs
Parameter
API Write logs digunakan untuk menulis log ke Simple Log Service. Setelah Anda membuat PackId secara manual, Anda harus menempatkan PackId tersebut pada properti LogTags dari LogGroup dalam permintaan PutLogs, dengan Key diatur ke __pack_id__. Berikut contoh parameternya:
{
"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"
}
]
}
]
}
Contoh kode
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 membuat PackId secara manual dan mengunggahnya dengan memanggil API PutLogs. Ganti parameter
project,logstore,endpoint,accessKeyId, danaccessKeySecretdengan nilai aktual Anda.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 instans 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 instans PackIdGenerator yang berbeda untuk konteks yang berbeda. PackIdGenerator generator2 = new PackIdGenerator(); System.out.println(generator2.generateNewPackId()); System.out.println(generator2.generateNewPackId()); // Konfigurasikan pengaturan 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); // Tambahkan PackId ke daftar tag. req.SetTags(Arrays.asList(new TagContent(TAG_PACK_ID, generator1.generateNewPackId()))); client.PutLogs(req); // Kirim permintaan log lainnya. 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 untuk menginstal SDK Go dan paket dependensi Protobuf.
go get -u github.com/aliyun/aliyun-log-go-sdk go get google.golang.org/protobuf -
Gunakan kode berikut untuk membuat PackId secara manual dan mengunggahnya menggunakan API PutLogs. Ganti parameter
project,logstore,endpoint,accessKeyId, danaccessKeySecretdengan nilai aktual Anda.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 instans PackIdGenerator yang sama untuk konteks yang sama. g1 := NewPackIdGenerator() fmt.Println(g1.Generate()) fmt.Println(g1.Generate()) fmt.Println(g1.Generate()) // Gunakan instans PackIdGenerator yang berbeda untuk konteks yang berbeda. g2 := NewPackIdGenerator() fmt.Println(g2.Generate()) fmt.Println(g2.Generate()) // Konfigurasikan pengaturan 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 PackId ke daftar tag. Value: proto.String(g1.Generate()), }, }, }, }) if err != nil { panic(err) } // Gunakan API PutLogs untuk menulis log. g1.Generate() membuat PackId baru. err = client.PutLogs(project, logstore, &sls.LogGroup{ Topic: &topic, Source: &source, Logs: logs, LogTags: []*sls.LogTag{ { Key: proto.String("__pack_id__"), // Tambahkan PackId 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, dan 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)) }
Menampilkan konteks log
-
Pada proyek Anda, klik logstore tujuan. Di tab , temukan entri log target lalu klik ikon
.CatatanPada setiap batch log yang dikirim menggunakan API PutLogs, log dengan awalan kontekstual
PackIdyang sama berbagi konteks log yang sama. Simple Log Service secara otomatis mengelompokkan log berdasarkanPackId. Klik Context View untuk melihat konteks log tertentu. Hal ini akan menampilkan kelompok log yang memiliki awalan kontekstual yang sama, dengan entri log target disorot.
-
Gulir ke atas atau ke bawah halaman untuk melihat konteks log.

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