Golang을 사용한 AWS CloudWatch 로깅

이 동영상에서는 AWS CloudWatch Logs의 작동 방식과 이를 Golang과 함께 효율적으로 사용하는 방법에 대해 자세히 설명합니다.



Youtube Video 에서 모든 것을 설명했기 때문에 이 게시물에서는 코드를 검토하지 않겠습니다. 하지만 여기 있습니다. Githubhere에서 최신 버전을 찾을 수 있습니다.

package main

import (...)

var (
    cwl           *cloudwatchlogs.CloudWatchLogs
    logGroupName  = "youtubeTest"
    logStreamName = ""
    sequenceToken = ""
)

func init() {
    sess, err := session.NewSessionWithOptions(session.Options{
        Config: aws.Config{
            Region: aws.String("eu-west-2"), // london
        },
    })

    if err != nil {
        panic(err)
    }

    cwl = cloudwatchlogs.New(sess)

    err = ensureLogGroupExists(logGroupName)
    if err != nil {
        panic(err)
    }

}

func main() {
    queue := []string{}
    lock := sync.Mutex{}

    go datasource.GenerateData(&queue, &lock)

    go processQueue(&queue, &lock)

    // to stop the code from exiting
    wg := sync.WaitGroup{}
    wg.Add(1)
    wg.Wait()

}

// ensureLogGroupExists first checks if the log group exists,
// if it doesn't it will create one.
func ensureLogGroupExists(name string) error {
    resp, err := cwl.DescribeLogGroups(&cloudwatchlogs.DescribeLogGroupsInput{})
    if err != nil {
        return err
    }

    for _, logGroup := range resp.LogGroups {
        if *logGroup.LogGroupName == name {
            return nil
        }
    }

    _, err = cwl.CreateLogGroup(&cloudwatchlogs.CreateLogGroupInput{
        LogGroupName: &name,
    })
    if err != nil {
        return err
    }

    _, err = cwl.PutRetentionPolicy(&cloudwatchlogs.PutRetentionPolicyInput{
        RetentionInDays: aws.Int64(14),
        LogGroupName:    &name,
    })

    return err
}

// createLogStream will make a new logStream with a random uuid as its name.
func createLogStream() error {
    name := uuid.New().String()

    _, err := cwl.CreateLogStream(&cloudwatchlogs.CreateLogStreamInput{
        LogGroupName:  &logGroupName,
        LogStreamName: &name,
    })

    logStreamName = name

    return err
}

// processQueue will process the log queue
func processQueue(queue *[]string, lock *sync.Mutex) error {
    var logQueue []*cloudwatchlogs.InputLogEvent

    for {
        lock.Lock()
        if len(*queue) > 0 {
            for _, item := range *queue {
                logQueue = append(logQueue, &cloudwatchlogs.InputLogEvent{
                    Message:   &item,
                    Timestamp: aws.Int64(time.Now().UnixNano() / int64(time.Millisecond)),
                })
            }

            *queue = []string{}
        }

        lock.Unlock()

        if len(logQueue) > 0 {
            input := cloudwatchlogs.PutLogEventsInput{
                LogEvents:    logQueue,
                LogGroupName: &logGroupName,
            }

            if sequenceToken == "" {
                err := createLogStream()
                if err != nil {
                    panic(err)
                }
            } else {
                input = *input.SetSequenceToken(sequenceToken)
            }

            input = *input.SetLogStreamName(logStreamName)

            resp, err := cwl.PutLogEvents(&input)
            if err != nil {
                log.Println(err)
            }

            if resp != nil {
                sequenceToken = *resp.NextSequenceToken
            }

            logQueue = []*cloudwatchlogs.InputLogEvent{}
        }

        time.Sleep(time.Second * 5)
    }

}


올바르게 완료되면 logGroup의 단일 logStream이 로그 메시지로 채워지는 것을 볼 수 있습니다.
여러 인스턴스를 실행 중인 경우(아래 그림과 같이) 여러 logStream이 표시될 수 있습니다.

좋은 웹페이지 즐겨찾기