Clue/log 패키지
개요
어느새 고아의 친구Clue를 만났는데 뭘 할 수 있는지 알아봤어요.잘 모르겠고 주관적인 것이 있으니 정확한 곳은 창고를 참조하세요(그리고 나무라세요).
Clue란?
이것은 마이크로 서비스 기능을 모은 라이브러리다.
여러 개의 포장으로 구성되어 있습니다.고아뿐만 아니라 마이크로 서비스의 사용도 구상했다(하지만 고아는 이를 적극적으로 이용하려는 것 같다).
Clue에서 제공하는 기능:
Logging: 컨텍스트 기반 레코더 제공
Metrics: Promaetheus 호환 가능
/metrics
HTTP 엔드포인트Health checks: 공개된 서비스의 건강검진 단점
Dependency mocks: 테스트용 모듈
Tracing: OpenTelemetry 사양에 따른 추적 요청
log 포장
로거context를콘텍트에서 미리 준비하려고 했는데 생각한 것 같아요.
package main
import (
"context"
"github.com/goadesign/clue/log"
)
func main() {
ctx := log.Context(context.Background()) // ← ここでロガーが ctx にセットされている
log.Printf(ctx, "hello %s", "world") // ← ctx からロガーを取り出してメッセージを表示する
log.Print(ctx, log.KV{"hello", "world"})
log.Print(ctx,
log.KV{"example", "log.KV"},
log.KV{"order", "deterministic"},
log.KV{"backed_by", "slice"},
)
log.Print(ctx, log.Fields{
"example": "log.Fields",
"order": "random",
"backed_by": "map",
})
}
OUTPUT:로그인
time=2022-02-22T02:22:02Z level=info msg="hello world"
time=2022-02-22T02:22:02Z level=info hello=world
time=2022-02-22T02:22:02Z level=info example=log.KV order=deterministic backed_by=slice
time=2022-02-22T02:22:02Z level=info order=random backed_by=map example=log.Fields
.Context에 가입하는 것 이외에 일반적인 로그와 다를 것이 없습니다.다만,
log.Context(ctx)
에서 로거를 설정하는 것은 이해하기 어렵다.// Context initializes a context for logging.
func Context(ctx context.Context, opts ...LogOption) context.Context {
l, ok := ctx.Value(ctxLogger).(*logger)
if !ok {
l = &logger{options: defaultOptions()}
}
l.lock.Lock()
defer l.lock.Unlock()
for _, opt := range opts {
opt(l.options)
}
if l.options.disableBuffering != nil && l.options.disableBuffering(ctx) {
l.flush()
}
return context.WithValue(ctx, ctxLogger, l)
}
무엇을 좋아하는지 말하자면ctx로 구동되는 기록기에 값을 설정하면 돌아가는 위치의 로그에 이 값을 설정하기 때문에 로그가 쉽게 이해된다.예를 들어 다음과 같이 키/value를 설정하면ctx := log.With(log.Context(context.Background()), log.KV{"user-id", 123})
이ctx에서 생성된 로그에는 반드시 user-id=123
와 같은 키/value가 있기 때문에 로그는 길을 잃지 않습니다.기타 몇 가지 기능이 있다.
완충
나는 로그에 이런 요구가 있다고 생각한다. 오류가 발생했을 때만 생각하고, 오류가 발생했을 때도 주변의 로그를 원한다.Clue에는 출력된 로그
log.Info(...)
를 버퍼로 출력할 때 출력하는 기능이 있습니다.log.Infof(ctx, "request started") // ← このログはまだ出力されない。バッファされるだけ
// ... ここで log.Infof(...) が何回か呼ばれるかも知れない
log.Errorf(ctx, err, "request failed") // ← ここで今までバッファリングしたログが出力されます
호출log.Errorf(...)
, Fatal
또는 Error
버퍼 메모리의 플래시 시간.또한 Flush
항상 버퍼링이 되지 않기 때문에 플래시 버퍼링 메시지를 보내지 않고 임의의 로그를 출력할 수 있습니다.버퍼링을 멈추고 로그를 강제로 출력할 수도 있습니다.
ctx := log.Context(req.Context(), log.WithDisableBuffering(log.IsTracing))
구조화 로그
키/value의 Logging 쌍을 사용할 수 있습니다.
ctx := log.Context(context.Background())
ctx := log.With(ctx, log.KV{"key2", "val2"})
log.Print(ctx, log.KV{"hello", "world 1"})
ctx = log.With(ctx, log.KV{"key3", "val3"})
log.Print(ctx, log.KV{"hello", "world 2"}, log.KV{"key4", "val4"})
로그 수준
로그 레벨은
Print
, debug
, info
세 가지 레벨이 있습니다.ctx := log.Context(context.Background())
log.Debugf(ctx, "debug message 1")
ctx := log.Context(ctx, log.WithDebug())
log.Debugf(ctx, "debug message 2")
log.Infof(ctx, "info message")
OUTPUT:DEBG[0000] msg="debug message 2"
INFO[0000] msg="info message"
erro
는 응용 시작 후의 초수입니다.로그 출력 위치
ctx := log.Context(context.Background(), log.WithOutput(os.Stderr))
log.Printf(ctx, "hello world")
로그 형식
로그 형식은 사용자 정의 형식기에서 수정할 수 있지만, 세 가지 삽입식 형식도 있다.
0000
time=2022-01-09T20:29:45Z level=info msg="hello world"
INFO[0000] msg="hello world"
사용자 정의 형식
func formatFunc(entry *log.Entry) []byte {
return []byte(fmt.Sprintf("%s: %s", entry.Severity, entry.Keyvals[0].V))
}
ctx := log.Context(context.Background(), log.WithFormat(formatFunc))
log.Printf(ctx, "hello world")
OUTPUT:INFO: hello world
HTTP 중간부품
전파 로그 상하문 생성 (기록기
{"time":"2022-01-09T20:29:45Z","level":"info","msg":"hello world"}
의 중간부품을 불러옵니다.로그가 필요 없는 경로를 정규 표현식으로 지정할 수 있기 때문에 특정한 경로만 기록할 수 없습니다. (건강검진을 배제할 수 있습니다.)gRPC 차단기
이상의 gRPC 버전입니다.
표준 로그와 호환
표준 로그 인터페이스와 호환됩니다.표준 로그
context.Context
를 사용하기 때문에 버퍼링을 하지 않습니다.표준 로그는 인터페이스에 정의되지 않았기 때문에 인터페이스를 만족시킬 수 있습니다.이런 곳이 있는 것 같은데, 어때요?🤔
Goa의 중간부품으로 사용
ctx := log.Context(context.Background())
logger := log.AsGoaMiddlewareLogger(ctx) // logger は middleware.Logger を満たします
Happy hacking!
Reference
이 문제에 관하여(Clue/log 패키지), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/ikawaha/articles/20220503-6677a85c121a27텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)