package controlplane import ( "strings" envoy_service_accesslog_v3 "github.com/envoyproxy/go-control-plane/envoy/service/accesslog/v3" "github.com/rs/zerolog" "github.com/pomerium/pomerium/internal/log" ) func (srv *Server) registerAccessLogHandlers() { envoy_service_accesslog_v3.RegisterAccessLogServiceServer(srv.GRPCServer, srv) } // StreamAccessLogs receives logs from envoy and prints them to stdout. func (srv *Server) StreamAccessLogs(stream envoy_service_accesslog_v3.AccessLogService_StreamAccessLogsServer) error { for { msg, err := stream.Recv() if err != nil { log.Error(stream.Context()).Err(err).Msg("access log stream error, disconnecting") return err } for _, entry := range msg.GetHttpLogs().LogEntry { reqPath := entry.GetRequest().GetPath() var evt *zerolog.Event if reqPath == "/ping" || reqPath == "/healthz" { evt = log.Debug(stream.Context()) } else { evt = log.Info(stream.Context()) } // common properties evt = evt.Str("service", "envoy") evt = evt.Str("upstream-cluster", entry.GetCommonProperties().GetUpstreamCluster()) // request properties evt = evt.Str("method", entry.GetRequest().GetRequestMethod().String()) evt = evt.Str("authority", entry.GetRequest().GetAuthority()) evt = evt.Str("path", stripQueryString(reqPath)) evt = evt.Str("user-agent", entry.GetRequest().GetUserAgent()) evt = evt.Str("referer", stripQueryString(entry.GetRequest().GetReferer())) evt = evt.Str("forwarded-for", entry.GetRequest().GetForwardedFor()) evt = evt.Str("request-id", entry.GetRequest().GetRequestId()) // response properties dur := entry.CommonProperties.TimeToLastDownstreamTxByte.AsDuration() evt = evt.Dur("duration", dur) evt = evt.Uint64("size", entry.Response.ResponseBodyBytes) evt = evt.Uint32("response-code", entry.GetResponse().GetResponseCode().GetValue()) evt = evt.Str("response-code-details", entry.GetResponse().GetResponseCodeDetails()) evt.Msg("http-request") } } } func stripQueryString(str string) string { if idx := strings.Index(str, "?"); idx != -1 { str = str[:idx] } return str }