全部產品
Search
文件中心

Simple Log Service:Go SDK快速入門

更新時間:Nov 21, 2024

本文介紹如何快速使用Log ServiceGo SDK完成常見操作,包括建立專案(Project)、建立日誌庫(Logstore)、寫入日誌和查詢日誌等。

前提條件

操作步驟

1.建立Project

名稱

類型

必填

描述

樣本值

description

string

Project描述。

this is test

projectName

string

Project名稱在阿里雲地區內全域唯一,建立後不可修改。其命名規則如下:

  • 只能包括小寫字母、數字和短劃線(-)。

  • 必須以小寫字母或者數字開頭和結尾。

  • 長度為 3-63 字元。

test-project


	// 建立Project。
	ProjectName := "aliyun-test-project"
	Description := "test"
	project, err := client.CreateProject(ProjectName, Description)
	if err != nil {
		if e, ok := err.(*sls.Error); ok && e.Code == "ProjectAlreadyExist" {
			log.Printf("Project : %s already created or has an global name conflict in Aliyun scope", ProjectName)
		} else {
			log.Fatalf("Create project : %s failed %v", ProjectName, err)
			os.Exit(1)
		}
	} else {
		log.Printf("Project : %s created successfully", project.Name)
		time.Sleep(60 * time.Second)
	}

2.建立Logstore

名稱

類型

必填

描述

樣本值

project

string

Project 名稱。

ali-test-project

logstoreName

string

Logstore 名稱。其命名規則如下:

  • 同一個 Project 下,Logstore 名稱不可重複。

  • 只能包括小寫字母、數字、短劃線(-)和底線(_)。

  • 必須以小寫字母或者數字開頭和結尾。

  • 長度為 3-63 字元。

my-logstore

shardCount

int

Shard分區個數。

2

ttl

int

資料的儲存時間,單位為天。取值範圍為1~3650。如果配置為3650,表示永久儲存。

1

autoSplit

bool

是否自動分裂Shard。

  • true:自動分裂Shard。

  • false:不自動分裂Shard。

true

maxSplitShard

int

自動分裂時最大的 Shard 個數,最小值是 1,最大值是 256。

說明

當 autoSplit 參數為 true 時必須設定。

64

	// 建立LogStore。
	LogStoreName := "aliyun-test-logstore"
	var ttl, shardCnt, maxSplitShard int = 3, 2, 64
	var autoSplit bool = true
	err = client.CreateLogStore(ProjectName, LogStoreName, ttl, shardCnt, autoSplit, maxSplitShard)
	if err != nil {
		if e, ok := err.(*sls.Error); ok && e.Code == "LogStoreAlreadyExist" {
			log.Printf("Logstore : %s already created", LogStoreName)
		} else {
			log.Fatalf("Create LogStore : %s failed %v", LogStoreName, err)
			os.Exit(1)
		}
	} else {
		log.Printf("Create logstore : %v successfully", LogStoreName)
		time.Sleep(10 * time.Second)
	}

3.建立索引

	// 為Logstore建立索引。
	index := sls.Index{
		// 欄位索引。
		Keys: map[string]sls.IndexKey{
			"col_0": {
				Token:         []string{" "},
				CaseSensitive: false,
				Type:          "long",
			},
			"col_1": {
				Token:         []string{",", ":", " "},
				CaseSensitive: false,
				Type:          "text",
			},
		},
		// 全文索引。
		Line: &sls.IndexLine{
			Token:         []string{",", ":", " "},
			CaseSensitive: false,
			IncludeKeys:   []string{},
			ExcludeKeys:   []string{},
		},
	}
	err = client.CreateIndex(ProjectName, LogStoreName, index)
	if err != nil {
		if e, ok := err.(*sls.Error); ok && e.Code == "IndexAlreadyExist" {
			log.Printf("Index : already created")
		} else {
			log.Fatalf("Create Index failed %v", err)
			os.Exit(1)
		}
	} else {
		log.Println("CreateIndex success")
		time.Sleep(60 * time.Second)
	}

4.寫入資料

參數

類型

是否必填

說明

project

string

目標Project。

logstore

string

目標LogStore。

topic

string

日誌主題。

說明

如果留空或沒有指定,該欄位將被賦予""。

source

string

發送源。

說明

如果留空或沒有指定,該欄位將被賦予producer所在宿主機的IP。

content

Slice

要發送的日誌/日誌列表。寫入日誌的格式為LogItem

	// 向Logstore寫入資料。
	for loggroupIdx := 0; loggroupIdx < 10; loggroupIdx++ {
		logs := []*sls.Log{}
		for logIdx := 0; logIdx < 100; logIdx++ {
			content := []*sls.LogContent{}
			for colIdx := 0; colIdx < 10; colIdx++ {
				if colIdx == 0 {
					content = append(content, &sls.LogContent{
						Key:   proto.String(fmt.Sprintf("col_%d", colIdx)),
						Value: proto.String(fmt.Sprintf("%d", rand.Intn(10000000))),
					})
				} else {
					content = append(content, &sls.LogContent{
						Key:   proto.String(fmt.Sprintf("col_%d", colIdx)),
						Value: proto.String(fmt.Sprintf("loggroup idx: %d, log idx: %d, col idx: %d, value: %d", loggroupIdx, logIdx, colIdx, rand.Intn(10000000))),
					})
				}
			}
			log := &sls.Log{
				Time:     proto.Uint32(uint32(time.Now().Unix())),
				Contents: content,
			}
			logs = append(logs, log)
		}
		loggroup := &sls.LogGroup{
			Topic:  proto.String("test"),
			Source: proto.String("203.0.x.x"),
			Logs:   logs,
		}

		err = client.PutLogs(ProjectName, LogStoreName, loggroup)
		if err != nil {
			log.Fatalf("PutLogs failed %v", err)
			os.Exit(1)
		}
		log.Println("PutLogs success")
		time.Sleep(time.Second)
	}

範例程式碼

本樣本中,建立一個SLSQuickStart.go檔案,並調用介面分別完成建立Project、建立Logstore、建立索引、寫入日誌資料和查詢日誌資料。樣本如下:

package main

import (
	"fmt"
	"log"
	"math/rand"
	"os"
	"time"

	sls "github.com/aliyun/aliyun-log-go-sdk"
	"github.com/gogo/protobuf/proto"
)

func main() {
	// Log Service的服務入口。此處以杭州為例,其它地區請根據實際情況填寫。
	Endpoint := "cn-hangzhou.log.aliyuncs.com"

	// 本樣本從環境變數中擷取AccessKey ID和AccessKey Secret。
	AccessKeyId := os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")
	AccessKeySecret := os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")
	// RAM使用者角色的臨時安全性權杖。此處取值為空白,表示不使用臨時安全性權杖。
	SecurityToken := ""
	// 建立Log ServiceClient。
	provider := sls.NewStaticCredentialsProvider(AccessKeyId, AccessKeySecret, SecurityToken)
	client := sls.CreateNormalInterfaceV2(Endpoint, provider)

	// 建立Project。
	ProjectName := "aliyun-test-project"
	Description := "test"
	project, err := client.CreateProject(ProjectName, Description)
	if err != nil {
		if e, ok := err.(*sls.Error); ok && e.Code == "ProjectAlreadyExist" {
			log.Printf("Project : %s already created or has an global name conflict in Aliyun scope", ProjectName)
		} else {
			log.Fatalf("Create project : %s failed %v", ProjectName, err)
			os.Exit(1)
		}
	} else {
		log.Printf("Project : %s created successfully", project.Name)
		time.Sleep(60 * time.Second)
	}

	// 建立LogStore。
	LogStoreName := "aliyun-test-logstore"
	err = client.CreateLogStore(ProjectName, LogStoreName, 3, 2, true, 6)
	if err != nil {
		if e, ok := err.(*sls.Error); ok && e.Code == "LogStoreAlreadyExist" {
			log.Printf("Logstore : %s already created", LogStoreName)
		} else {
			log.Fatalf("Create LogStore : %s failed %v", LogStoreName, err)
			os.Exit(1)
		}
	} else {
		log.Printf("Create logstore : %v successfully", LogStoreName)
		time.Sleep(10 * time.Second)
	}

	// 為Logstore建立索引。
	index := sls.Index{
		// 欄位索引。
		Keys: map[string]sls.IndexKey{
			"col_0": {
				Token:         []string{" "},
				CaseSensitive: false,
				Type:          "long",
			},
			"col_1": {
				Token:         []string{",", ":", " "},
				CaseSensitive: false,
				Type:          "text",
			},
		},
		// 全文索引。
		Line: &sls.IndexLine{
			Token:         []string{",", ":", " "},
			CaseSensitive: false,
			IncludeKeys:   []string{},
			ExcludeKeys:   []string{},
		},
	}
	err = client.CreateIndex(ProjectName, LogStoreName, index)
	if err != nil {
		if e, ok := err.(*sls.Error); ok && e.Code == "IndexAlreadyExist" {
			log.Printf("Index : already created")
		} else {
			log.Fatalf("Create Index failed %v", err)
			os.Exit(1)
		}
	} else {
		log.Println("CreateIndex success")
		time.Sleep(60 * time.Second)
	}

	// 向Logstore寫入資料。
	for loggroupIdx := 0; loggroupIdx < 10; loggroupIdx++ {
		logs := []*sls.Log{}
		for logIdx := 0; logIdx < 100; logIdx++ {
			content := []*sls.LogContent{}
			for colIdx := 0; colIdx < 10; colIdx++ {
				if colIdx == 0 {
					content = append(content, &sls.LogContent{
						Key:   proto.String(fmt.Sprintf("col_%d", colIdx)),
						Value: proto.String(fmt.Sprintf("%d", rand.Intn(10000000))),
					})
				} else {
					content = append(content, &sls.LogContent{
						Key:   proto.String(fmt.Sprintf("col_%d", colIdx)),
						Value: proto.String(fmt.Sprintf("loggroup idx: %d, log idx: %d, col idx: %d, value: %d", loggroupIdx, logIdx, colIdx, rand.Intn(10000000))),
					})
				}
			}
			log := &sls.Log{
				Time:     proto.Uint32(uint32(time.Now().Unix())),
				Contents: content,
			}
			logs = append(logs, log)
		}
		loggroup := &sls.LogGroup{
			Topic:  proto.String("test"),
			Source: proto.String("203.0.113.10"),
			Logs:   logs,
		}

		err = client.PutLogs(ProjectName, LogStoreName, loggroup)
		if err != nil {
			log.Fatalf("PutLogs failed %v", err)
			os.Exit(1)
		}
		log.Println("PutLogs success")
		time.Sleep(time.Second)
	}

	// 通過SQL查詢日誌。
	// 當語句僅含查詢語句時,line、offset、reverse取值有效。line為每次擷取的最大日誌條數,最大值為100,offset為起始位置。通過line與offset參數可以實現翻頁效果。
	// 例如首次查詢line=100、offset=0, 第二次查詢line = 100、offset=100。
	// 當語句包含分析語句時,line、offset、reverse取值無效,以分析語句的limit、offset、order by子句為準,此時建議line、offset、reverse填寫0、0、false(其他值會報錯)。
	// 更多資訊,請參見分頁顯示查詢分析結果。
	response, err := client.GetLogs(ProjectName, LogStoreName, "test", time.Now().Unix()-1800, time.Now().Unix(), "* and col_0 > 9000000", 100, 1, true)
	if err != nil {
		log.Fatalf("GetLogs failed %v", err)
		os.Exit(1)
	}
	log.Printf("Get %d logs", response.Count)
	logs := response.Logs
	for i := range logs {
		for k, v := range logs[i] {
			log.Printf("key: %s, value: %s", k, v)
		}
		log.Println("======")
	}
}

更多範例程式碼,請參見Aliyun Log Go SDK

返回結果

返回結果樣本如下:

Project : aliyun-test-project created successfully.
Create logstore : aliyun-test-logstore successfully.
CreateIndex success
PutLogs success
PutLogs success
PutLogs success
PutLogs success
PutLogs success
PutLogs success
PutLogs success
PutLogs success
PutLogs success
PutLogs success
Get 61 logs
key: source, value: 203.0.113.10
key: time, value: 1627282116
key: col_0, value: 9886757
key: col_1, value: loggroup idx: 6, log idx: 87, col idx: 1, value: 2673724
key: col_2, value: loggroup idx: 6, log idx: 87, col idx: 2, value: 5822012
key: col_8, value: loggroup idx: 6, log idx: 87, col idx: 8, value: 3996746
key: topic, value: test
key: col_9, value: loggroup idx: 6, log idx: 87, col idx: 9, value: 7646111
key: col_3, value: loggroup idx: 6, log idx: 87, col idx: 3, value: 8872632
key: col_4, value: loggroup idx: 6, log idx: 87, col idx: 4, value: 1839836
key: col_5, value: loggroup idx: 6, log idx: 87, col idx: 5, value: 6967415
key: col_6, value: loggroup idx: 6, log idx: 87, col idx: 6, value: 5872057
key: col_7, value: loggroup idx: 6, log idx: 87, col idx: 7, value: 3227909
======
......