すべてのプロダクト
Search
ドキュメントセンター

Simple Log Service:PackId を使用したログコンテキストの関連付け

最終更新日:Aug 27, 2026

コンテキストクエリは、特定のソースから対象のログの直前と直後のログを検索します。大量のログを処理する場合は、PackId を割り当てて関連ログをグループ化することで、コンテキストを高速かつ完全に取得できます。

仕組み

PackId は、コンテキストプレフィックス-ロググループ ID という形式です。例: 5FA51423DDB54FDA-1E3

  • コンテキストプレフィックス: 5FA51423DDB54FDA のような大文字の 16 進数です。コンテキストプレフィックスを共有するログは、同じログコンテキストに属します。

  • ロググループ ID: 1E3 のような大文字の 16 進数です。ログコンテキスト内では、ロググループ ID は順次インクリメントされます。たとえば、1E3 と 1E4 は隣接するグループです。

クライアントは PackId を生成し、ログ書き込みリクエストとともに送信します。Simple Log Service は、コンテキストプレフィックスを共有するログを同じログコンテキストにグループ化します。

__pack_meta__ は、Simple Log Service によって生成されるシステムフィールドです。元のファイル内のログの場所を記録し、host、file_path、log_offset、および log_size のみを含みます。GetLogs API はこのフィールドを返し、このフィールドはログコンテキストをクエリするための GetContextLogs API の必須パラメーターです。__pack_meta__ は、Logtail によって収集されたログ、またはプロデューサー SDK を使用して書き込まれたログに対してのみ自動的に生成されます。

PackId の自動生成

  • プロデューサー SDK を使用して書き込まれたログ: 同じプロデューサーインスタンスからのログはコンテキストを共有し、コンテキストクエリが可能です。Aliyun Log Java Producer と C Producer SDK は、PackId を自動的に生成してアタッチします。

  • Logtail によって収集されたログ: Logtail は PackId を自動的に生成してアタッチします。同じホストまたは Pod 上の同じファイルからのログはコンテキストを共有し、コンテキストクエリが可能です。

PutLogs API を使用した PackId の手動生成

パラメーター

PutLogs API を呼び出す際、PutLogs リクエストに含まれる LogGroup の LogTags 属性に PackId を含めます。Key には __pack_id__ を設定します。

{
  "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"
            }
        ]
     }
   ]
}

サンプルコード

Java の例

  1. 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>
  2. 次のコードを実行して PackId を生成し、PutLogs を使用してアップロードします。project、logstore、endpoint、accessKeyId、および accessKeySecret を実際の値に置き換えてください。

    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!");
            // 同じコンテキストには同じ PackIdGenerator インスタンスを使用します。
            PackIdGenerator generator1 = new PackIdGenerator();
            System.out.println(generator1.generateNewPackId());
            System.out.println(generator1.generateNewPackId());
            System.out.println(generator1.generateNewPackId());
            // 異なるコンテキストには異なる PackIdGenerator インスタンスを使用します。
            PackIdGenerator generator2 = new PackIdGenerator();
            System.out.println(generator2.generateNewPackId());
            System.out.println(generator2.generateNewPackId());
            // ログパラメーターを設定します。
            String project = "your-project-name";
            String logstore = "your-logstore-name";
            String topic = "your-topic";
            String source = "127.0.0.1";
            Client client = new Client("your-endpoint", "your-access-key-id", "your-access-key-secret");
            List<LogItem> logs = new ArrayList<>();
            LogItem log = new LogItem();
            log.PushBack("hello", "world");
            logs.add(log);
            // ログリクエストを送信します。
            PutLogsRequest req = new PutLogsRequest(project, logstore, topic, source, logs);
            // タグリストに PackId を追加します。
            req.SetTags(Arrays.asList(new TagContent(TAG_PACK_ID, generator1.generateNewPackId())));
            client.PutLogs(req);
            // 別のログリクエストを送信します。
            PutLogsRequest req2 = new PutLogsRequest(project, logstore, topic, source, logs);
            req2.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) {
                    // 例外は無視します。
                }
                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("Failed to get local machine ip, set ip to 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();
            }
        }
    }

    サンプルコードのパラメーター

    パラメーター

    説明

    例

    project

    Simple Log Service のプロジェクト名です。

    test-project

    logstore

    Simple Log Service の Logstore 名です。

    test-logstore

    endpoint

    Simple Log Service のパブリックエンドポイントです。エンドポイントをご参照ください。

    cn-hangzhou.log.aliyuncs.com

    accessKeyId

    AccessKey ID です。AccessKey の作成をご参照ください。

    LTAI****************

    accessKeySecret

    AccessKey Secret です。AccessKey の作成をご参照ください。

    yourAccessKeySecret

Go の例

  1. Go SDK と protobuf の依存関係をインストールします。

    go get -u github.com/aliyun/aliyun-log-go-sdk
    go get google.golang.org/protobuf
  2. 次のコードを実行して PackId を生成し、PutLogs を使用してアップロードします。project、logstore、endpoint、accessKeyId、および accessKeySecret を実際の値に置き換えてください。

    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() {
    	// 同じコンテキストには同じ PackIdGenerator インスタンスを使用します。
    	g1 := NewPackIdGenerator()
    	fmt.Println(g1.Generate())
    	fmt.Println(g1.Generate())
    	fmt.Println(g1.Generate())
    	// 異なるコンテキストには異なる PackIdGenerator インスタンスを使用します。
    	g2 := NewPackIdGenerator()
    	fmt.Println(g2.Generate())
    	fmt.Println(g2.Generate())
    	// ログパラメーターを設定します。
    	project := "your-project-name"
    	logstore := "your-logstore-name"
    	topic := "your-topic"
    	source := "your-source"
    	client := sls.CreateNormalInterface("your-endpoint", "your-access-key-id", "your-access-key-secret", "")
    	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"),
    				},
    			},
    		},
    	}
    	// PostLogStoreLogsV2 API を使用してログを書き込みます。
    	err := client.PostLogStoreLogsV2(project, logstore, &sls.PostLogStoreLogsRequest{
    		LogGroup: &sls.LogGroup{
    			Topic:  &topic,
    			Source: &source,
    			Logs:   logs,
    			LogTags: []*sls.LogTag{
    				{
    					Key:   proto.String("__pack_id__"), // タグリストに PackId を追加します。
    					Value: proto.String(g1.Generate()),
    				},
    			},
    		},
    	})
    	if err != nil {
    		panic(err)
    	}
    	// PutLogs API を使用してログを書き込みます。g1.Generate() は新しい PackId を生成します。
    	err = client.PutLogs(project, logstore, &sls.LogGroup{
    		Topic:  &topic,
    		Source: &source,
    		Logs:   logs,
    		LogTags: []*sls.LogTag{
    			{
    				Key:   proto.String("__pack_id__"), // タグリストに PackId を追加します。
    				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))
    }
    // ホスト名、PID、時刻からコンテキストを生成します。
    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))
    }
    

    サンプルコードのパラメーター

    パラメーター

    説明

    例

    project

    Simple Log Service のプロジェクト名です。

    test-project

    logstore

    Simple Log Service の Logstore 名です。

    test-logstore

    endpoint

    Simple Log Service のパブリックエンドポイントです。エンドポイントをご参照ください。

    cn-hangzhou.log.aliyuncs.com

    accessKeyId

    AccessKey ID です。AccessKey の作成をご参照ください。

    LTAI****************

    accessKeySecret

    AccessKey Secret です。AccessKey の作成をご参照ください。

    yourAccessKeySecret

PutLogs API を使用して LogTags に __pack_id__ を設定すると、PackId 識別子のみが保存されます。__pack_meta__ は生成されないため、結果のログは GetContextLogs API を使用してクエリできません。ログコンテキストをクエリするには、代わりに Logtail を使用してログを収集するか、プロデューサー SDK を使用してログを書き込みます。

次のシナリオでも、デフォルトでは __pack_meta__ は生成されません:

  • Docker json-file logging driver: ログは {log, stream, time} 形式であり、PackId は含まれません。

  • Kubernetes: pod_name や namespace などのログフィールドは __tag__ フィールドに保存され、__pack_meta__ の生成には使用されません。

ログコンテキストの表示

  1. プロジェクトで、ターゲットの Logstore をクリックします。[生ログ] > [生データ] タブで、ターゲットログを見つけ、Context query icon アイコンをクリックします。

    説明

    PutLogs 経由で送信された、同じ PackId コンテキストプレフィックスを持つログは、同じログコンテキストにグループ化されます。[コンテキストビュー] をクリックすると、同じコンテキストプレフィックスを共有するロググループが表示され、対象のログがハイライト表示されます。

    時間範囲 (例: [15 分]) を設定し、[クエリ/分析] をクリックします。

  2. ページをスクロールして、選択したログのコンテキストを表示します。

    [コンテキストビュー] パネルでは、現在のログがハイライトされます。[古いログ] と [新しいログ] を使用して、隣接するログを閲覧します。[すべてのフィールド] からフィールドを選択するか、キーワードを入力して一致する箇所をハイライトします。

関連ドキュメント