// NewContextErrorGeneric ... func NewContextErrorGeneric(logger log.Logger, err error) *log.Context { if code := grpc.Code(err); code != codes.Unknown { return log.NewContext(logger).With(sklog.KeyMessage, grpc.ErrorDesc(err), "code", code.String()) } return log.NewContext(logger).With(sklog.KeyMessage, grpc.ErrorDesc(err)) }
func (m *MultitenantInstancer) Get(instanceID flux.InstanceID) (*Instance, error) { c, err := m.DB.GetConfig(instanceID) if err != nil { return nil, errors.Wrap(err, "getting instance config from DB") } // Platform interface for this instance platform, err := m.Connecter.Connect(instanceID) if err != nil { return nil, errors.Wrap(err, "connecting to platform") } // Logger specialised to this instance instanceLogger := log.NewContext(m.Logger).With("instanceID", instanceID) // Registry client with instance's config creds, err := registry.CredentialsFromConfig(c.Settings) if err != nil { return nil, errors.Wrap(err, "decoding registry credentials") } regClient := ®istry.Client{ Credentials: creds, Logger: log.NewContext(instanceLogger).With("component", "registry"), } repo := gitRepoFromSettings(c.Settings) // Events for this instance eventRW := EventReadWriter{instanceID, m.History} var eventW history.EventWriter = eventRW if c.Settings.Slack.HookURL != "" { eventW = history.TeeWriter(eventRW, history.NewSlackEventWriter( http.DefaultClient, c.Settings.Slack.HookURL, c.Settings.Slack.Username, `Regrade`, // only catch the final message )) } // Configuration for this instance config := configurer{instanceID, m.DB} return New( platform, regClient, config, repo, instanceLogger, m.Histogram, eventRW, eventW, ), nil }
// Test that Context.Log has a consistent function stack depth when binding // log.Valuers, regardless of how many times Context.With has been called or // whether Context.Log is called via an interface typed variable or a concrete // typed variable. func TestContextStackDepth(t *testing.T) { t.Parallel() fn := fmt.Sprintf("%n", stack.Caller(0)) var output []interface{} logger := log.Logger(log.LoggerFunc(func(keyvals ...interface{}) error { output = keyvals return nil })) stackValuer := log.Valuer(func() interface{} { for i, c := range stack.Trace() { if fmt.Sprintf("%n", c) == fn { return i } } t.Fatal("Test function not found in stack trace.") return nil }) concrete := log.NewContext(logger).With("stack", stackValuer) var iface log.Logger = concrete // Call through interface to get baseline. iface.Log("k", "v") want := output[1].(int) for len(output) < 10 { concrete.Log("k", "v") if have := output[1]; have != want { t.Errorf("%d Withs: have %v, want %v", len(output)/2-1, have, want) } iface.Log("k", "v") if have := output[1]; have != want { t.Errorf("%d Withs: have %v, want %v", len(output)/2-1, have, want) } wrapped := log.NewContext(concrete) wrapped.Log("k", "v") if have := output[1]; have != want { t.Errorf("%d Withs: have %v, want %v", len(output)/2-1, have, want) } concrete = concrete.With("k", "v") iface = concrete } }
func Register() { logger := klog.NewLogfmtLogger(os.Stderr) ctx := context.Background() fieldKeys := []string{"method", "error"} requestCount := kitprometheus.NewCounter(stdprometheus.CounterOpts{ Namespace: "my_group", Subsystem: "string_service", Name: "request_count", Help: "Number of requests received.", }, fieldKeys) requestLatency := metrics.NewTimeHistogram(time.Microsecond, kitprometheus.NewSummary(stdprometheus.SummaryOpts{ Namespace: "my_group", Subsystem: "string_service", Name: "request_latency_microseconds", Help: "Total duraction of the requests in microseconds.", }, fieldKeys)) countResult := kitprometheus.NewSummary(stdprometheus.SummaryOpts{ Namespace: "my_group", Subsystem: "string_service", Name: "count_result", Help: "The result of each count method.", }, []string{}) var svc StringService svc = stringService{} svc = appLoggingMiddleware{logger, svc} svc = instrumentingMiddleware{requestCount, requestLatency, countResult, svc} uppercaseHandler := httptransport.Server{ Context: ctx, Endpoint: loggingMiddleware(klog.NewContext(logger).With("method", "uppercase"))(makeUppercaseEndpoint(svc)), DecodeRequestFunc: decodeUppercaseRequest, EncodeResponseFunc: encodeResponse, } countHandler := httptransport.Server{ Context: ctx, Endpoint: loggingMiddleware(klog.NewContext(logger).With("method", "count"))(makeCountEndpoint(svc)), DecodeRequestFunc: decodeCountRequest, EncodeResponseFunc: encodeResponse, } http.Handle("/uppercase", uppercaseHandler) http.Handle("/count", countHandler) http.Handle("/metrics", stdprometheus.Handler()) log.Fatal(http.ListenAndServe(":8901", nil)) }
func TestContextMissingValue(t *testing.T) { t.Parallel() var output []interface{} logger := log.Logger(log.LoggerFunc(func(keyvals ...interface{}) error { output = keyvals return nil })) lc := log.NewContext(logger) lc.Log("k") if want, have := 2, len(output); want != have { t.Errorf("want len(output) == %v, have %v", want, have) } if want, have := log.ErrMissingValue, output[1]; want != have { t.Errorf("want %#v, have %#v", want, have) } lc.With("k1").WithPrefix("k0").Log("k2") if want, have := 6, len(output); want != have { t.Errorf("want len(output) == %v, have %v", want, have) } for i := 1; i < 6; i += 2 { if want, have := log.ErrMissingValue, output[i]; want != have { t.Errorf("want output[%d] == %#v, have %#v", i, want, have) } } }
func main() { // setup a logger logger = log.NewLogfmtLogger(os.Stderr) logger = log.NewContext(logger).With("svc", "sensor").With("caller", log.DefaultCaller) // setup rethinkdb session session := getSession() // build the context ctx := context.Background() // new service svc := NewSensorService(session) // wrap it in the logging middleware svc = loggingMiddleware(logger)(svc) // bind the service to HTTP with the context // with it's matching encoder/decoder recordHandler := httptransport.NewServer( ctx, makeRecordEndpoint(svc), decodeRecordRequest, encodeResponse, ) // assign an endpoint route http.Handle("/sensor/record", recordHandler) // bind the listener logger.Log("msg", "HTTP", "addr", ":5000") logger.Log("err", http.ListenAndServe(":5000", nil)) }
func NewHandler(s api.FluxService, r *mux.Router, logger log.Logger, h metrics.Histogram) http.Handler { for method, handlerFunc := range map[string]func(api.FluxService) http.Handler{ "ListServices": handleListServices, "ListImages": handleListImages, "PostRelease": handlePostRelease, "GetRelease": handleGetRelease, "Automate": handleAutomate, "Deautomate": handleDeautomate, "Lock": handleLock, "Unlock": handleUnlock, "History": handleHistory, "GetConfig": handleGetConfig, "SetConfig": handleSetConfig, "RegisterDaemon": handleRegister, "IsConnected": handleIsConnected, } { var handler http.Handler handler = handlerFunc(s) handler = logging(handler, log.NewContext(logger).With("method", method)) handler = observing(handler, h.With("method", method)) r.Get(method).Handler(handler) } return r }
func main() { // `package log` domain var logger kitlog.Logger logger = kitlog.NewLogfmtLogger(os.Stderr) logger = kitlog.NewContext(logger).With("ts", kitlog.DefaultTimestampUTC) stdlog.SetOutput(kitlog.NewStdlibAdapter(logger)) // redirect stdlib logging to us stdlog.SetFlags(0) // flags are handled in our logger // read configuration from environment c, err := config.LoadConfiguration() if err != nil { logger.Log("fatal", err.Error()) return } // Mechanical stuff rand.Seed(time.Now().UnixNano()) root := context.Background() errc := make(chan error) go func() { errc <- interrupt() }() // Start bindings binding.StartApplicationSQSConsumer(logger, root, errc, c) binding.StartHealthCheckHTTPListener(logger, root, errc, c) logger.Log("fatal", <-errc) }
func Example_context() { logger := log.NewLogfmtLogger(os.Stdout) type Task struct { ID int Cmd string } taskHelper := func(cmd string, logger log.Logger) { // execute(cmd) logger.Log("cmd", cmd, "dur", 42*time.Millisecond) } RunTask := func(task Task, logger log.Logger) { logger = log.NewContext(logger).With("taskID", task.ID) logger.Log("event", "starting task") taskHelper(task.Cmd, logger) logger.Log("event", "task complete") } RunTask(Task{ID: 1, Cmd: "echo Hello, world!"}, logger) // Output: // taskID=1 event="starting task" // taskID=1 cmd="echo Hello, world!" dur=42ms // taskID=1 event="task complete" }
// NewContextErrorGeneric creates context for given error. // Performs error type check internally to choose strategy that fits the best. func NewContextError(logger log.Logger, err error) *log.Context { if ctx, ok := err.(sklog.Contexter); ok { return log.NewContext(logger).With(ctx.Context()) } switch e := err.(type) { case *json.MarshalerError: return NewContextJSONMarshalerError(logger, e) case *json.InvalidUnmarshalError: return NewContextJSONInvalidUnmarshalError(logger, e) case *json.UnmarshalFieldError: return NewContextJSONUnmarshalFieldError(logger, e) case *json.UnmarshalTypeError: return NewContextJSONUnmarshalTypeError(logger, e) case *json.UnsupportedTypeError: return NewContextJSONUnsupportedTypeError(logger, e) case *json.UnsupportedValueError: return NewContextJSONUnsupportedValueError(logger, e) case *json.InvalidUTF8Error: return NewContextJSONInvalidUTF8Error(logger, e) case *json.SyntaxError: return NewContextJSONSyntaxError(logger, e) default: return sklog.NewContextErrorGeneric(logger, e) } }
// NewRegistrar returns a Consul Registrar acting on the provided catalog // registration. func NewRegistrar(client Client, r *stdconsul.AgentServiceRegistration, logger log.Logger) *Registrar { return &Registrar{ client: client, registration: r, logger: log.NewContext(logger).With("service", r.Name, "tags", fmt.Sprint(r.Tags), "address", r.Address), } }
func main() { logger := log.NewLogfmtLogger(os.Stderr) logger = log.NewContext(logger).With("ts", log.DefaultTimestampUTC) err := godotenv.Load() if err != nil { logger.Log("level", "fatal", "err", err) } config := &Config{ Addr: os.Getenv("ADDR"), DSN: os.Getenv("DSN"), } db, err := gorm.Open("postgres", config.DSN) if err != nil { panic(err) } app := cli.NewApp() app.Commands = []cli.Command{{ Name: "serve", Action: serve(logger, config, db), }} if err := app.Run(os.Args); err != nil { logger.Log("level", "fatal", "err", err) } }
// NewEndpointCache produces a new EndpointCache, ready for use. Instance // strings will be converted to endpoints via the provided factory function. // The logger is used to log errors. func NewEndpointCache(f Factory, logger log.Logger) *EndpointCache { return &EndpointCache{ f: f, m: map[string]endpointCloser{}, logger: log.NewContext(logger).With("component", "Endpoint Cache"), } }
func TestContext(t *testing.T) { t.Parallel() buf := &bytes.Buffer{} logger := log.NewLogfmtLogger(buf) kvs := []interface{}{"a", 123} lc := log.NewContext(logger).With(kvs...) kvs[1] = 0 // With should copy its key values lc = lc.With("b", "c") // With should stack if err := lc.Log("msg", "message"); err != nil { t.Fatal(err) } if want, have := "a=123 b=c msg=message\n", buf.String(); want != have { t.Errorf("\nwant: %shave: %s", want, have) } buf.Reset() lc = lc.WithPrefix("p", "first") if err := lc.Log("msg", "message"); err != nil { t.Fatal(err) } if want, have := "p=first a=123 b=c msg=message\n", buf.String(); want != have { t.Errorf("\nwant: %shave: %s", want, have) } }
func main() { logger = log.NewLogfmtLogger(os.Stderr) logger = log.NewContext(logger).With("ts", log.DefaultTimestampUTC, "caller", log.DefaultCaller) logger.Log("msg", "Starting bikefinder") var err error db_url := os.Getenv("DATABASE_URL") DB, err = crud.Connect("mysql", db_url) if err != nil { logger.Log("msg", "Failed to connect to db at "+db_url, "error", err) panic(err) } err = DB.CreateTables(DockingStationStatus{}) if err != nil { logger.Log("msg", "Failed to create db table", "error", err) panic(err) } http.HandleFunc("/schemes", getSchemes) http.HandleFunc("/stations", getStationsInside) http.HandleFunc("/bikes-near", getBikesNear) http.HandleFunc("/freedocks-near", getFreeDocksNear) http.HandleFunc("/map", getMap) http.HandleFunc("/ingest", ingest) http.Handle("/", http.FileServer(http.Dir("./static"))) bind := fmt.Sprintf("%s:%s", os.Getenv("OPENSHIFT_GO_IP"), os.Getenv("OPENSHIFT_GO_PORT")) logger.Log("msg", "Attempting to listen on "+bind) err = http.ListenAndServe(bind, nil) if err != nil { logger.Log("msg", "Failed to listen", "error", err) panic(err) } }
func (s *Server) createConnection(conn *net.TCPConn) *connection { connID := atomic.AddUint64(&s.connCounter, 1) // child context with the connection id ctx := context.WithValue(s.Context, ConnID, connID) // logger with connection id as prefix logger := kitlog.NewContext(s.Logger).WithPrefix(ConnID, strconv.FormatUint(connID, 16)) // child context with the new logger ctx = context.WithValue(ctx, LoggerKey, logger) // pipe to move bytes from connection to the protocol pr, pw := io.Pipe() gc := &connection{ st: &s.t, id: connID, ctx: ctx, logger: logger, conn: conn, readTimeout: s.ReadTimeout, writeTimeout: s.WriteTimeout, pw: pw, p: s.ProtocolFactory(ctx, pr), } return gc }
// copied from log/benchmark_test.go func benchmarkRunner(b *testing.B, logger log.Logger, f func(log.Logger)) { lc := log.NewContext(logger).With("common_key", "common_value") b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { f(lc) } }
func main() { var ( listen = flag.String("listen", ":8080", "HTTP listen address") proxy = flag.String("proxy", "", "Optional comma-separated list of URLs to proxy uppercase requests") ) flag.Parse() var logger log.Logger logger = log.NewLogfmtLogger(os.Stderr) logger = log.NewContext(logger).With("listen", *listen).With("caller", log.DefaultCaller) ctx := context.Background() fieldKeys := []string{"method", "error"} requestCount := kitprometheus.NewCounter(stdprometheus.CounterOpts{ Namespace: "my_group", Subsystem: "string_service", Name: "request_count", Help: "Number of requests received.", }, fieldKeys) requestLatency := metrics.NewTimeHistogram(time.Microsecond, kitprometheus.NewSummary(stdprometheus.SummaryOpts{ Namespace: "my_group", Subsystem: "string_service", Name: "request_latency_microseconds", Help: "Total duration of requests in microseconds.", }, fieldKeys)) countResult := kitprometheus.NewSummary(stdprometheus.SummaryOpts{ Namespace: "my_group", Subsystem: "string_service", Name: "count_result", Help: "The result of each count method.", }, []string{}) var svc StringService svc = stringService{} svc = proxyingMiddleware(*proxy, ctx, logger)(svc) svc = loggingMiddleware(logger)(svc) svc = instrumentingMiddleware(requestCount, requestLatency, countResult)(svc) uppercaseHandler := httptransport.NewServer( ctx, makeUppercaseEndpoint(svc), decodeUppercaseRequest, encodeResponse, ) countHandler := httptransport.NewServer( ctx, makeCountEndpoint(svc), decodeCountRequest, encodeResponse, ) http.Handle("/uppercase", uppercaseHandler) http.Handle("/count", countHandler) http.Handle("/metrics", stdprometheus.Handler()) logger.Log("msg", "HTTP", "addr", *listen) logger.Log("err", http.ListenAndServe(*listen, nil)) }
func TestNopLogger(t *testing.T) { logger := log.NewNopLogger() if err := logger.Log("abc", 123); err != nil { t.Error(err) } if err := log.NewContext(logger).With("def", "ghi").Log(); err != nil { t.Error(err) } }
func BenchmarkValueBindingTimestamp(b *testing.B) { logger := log.NewNopLogger() lc := log.NewContext(logger).With("ts", log.DefaultTimestamp) b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { lc.Log("k", "v") } }
func BenchmarkValueBindingCaller(b *testing.B) { logger := discard lc := log.NewContext(logger).With("caller", log.DefaultCaller) b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { lc.Log("k", "v") } }
func BenchmarkOneWith(b *testing.B) { logger := discard lc := log.NewContext(logger).With("k", "v") b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { lc.Log("k", "v") } }
func main() { var ( httpAddr = flag.String("http.addr", ":8080", "HTTP listen address") maildir = flag.String("maildir", ".Maildir", "Maildir directory path") ) flag.Parse() var logger log.Logger { logger = log.NewLogfmtLogger(os.Stderr) logger = log.NewContext(logger).With("ts", log.DefaultTimestampUTC) logger = log.NewContext(logger).With("caller", log.DefaultCaller) } var ctx context.Context { ctx = context.Background() } var s restsvc.Service { s = restsvc.NewInmemService(*maildir) s = restsvc.LoggingMiddleware(logger)(s) } var h http.Handler { h = restsvc.MakeHTTPHandler(ctx, s, log.NewContext(logger).With("component", "HTTP")) } errs := make(chan error) go func() { c := make(chan os.Signal) signal.Notify(c, syscall.SIGINT, syscall.SIGTERM) errs <- fmt.Errorf("%s", <-c) }() go func() { logger.Log("transport", "HTTP", "addr", *httpAddr) errs <- http.ListenAndServe(*httpAddr, handlers.CORS()(h)) }() logger.Log("exit", <-errs) }
func NewSlackGateway(cfg config.SlackGateway) *SlackGateway { client := slacker.NewAPIClient(cfg.Token, "") gw := &SlackGateway{ id: "slack", cfg: cfg, client: client, logger: kitlog.NewContext(log.Logger).With("m", "Gateway-Slack"), } return gw }
// NewRegistrar returns a etcd Registrar acting on the provided catalog // registration. func NewRegistrar(client Client, service Service, logger log.Logger) *Registrar { return &Registrar{ client: client, service: service, logger: log.NewContext(logger).With( "value", service.Value, "key", service.Key, ), } }
func main() { var ( httpAddr = flag.String("http.addr", ":8080", "HTTP listen address") ) flag.Parse() var logger log.Logger { logger = log.NewLogfmtLogger(os.Stderr) logger = log.NewContext(logger).With("ts", log.DefaultTimestampUTC) logger = log.NewContext(logger).With("caller", log.DefaultCaller) } var ctx context.Context { ctx = context.Background() } var s ProfileService { s = newInmemService() s = loggingMiddleware{s, log.NewContext(logger).With("component", "svc")} } var h http.Handler { h = makeHandler(ctx, s, log.NewContext(logger).With("component", "http")) } errs := make(chan error, 2) go func() { logger.Log("transport", "http", "address", *httpAddr, "msg", "listening") errs <- http.ListenAndServe(*httpAddr, h) }() go func() { c := make(chan os.Signal) signal.Notify(c, syscall.SIGINT) errs <- fmt.Errorf("%s", <-c) }() logger.Log("terminated", <-errs) }
// NewRegistrar returns a ZooKeeper Registrar acting on the provided catalog // registration. func NewRegistrar(client Client, service Service, logger log.Logger) *Registrar { return &Registrar{ client: client, service: service, logger: log.NewContext(logger).With( "service", service.Name, "path", service.Path, "data", string(service.Data), ), } }
// NewEndpointCache produces a new EndpointCache, ready for use. Instance // strings will be converted to endpoints via the provided factory function. // The logger is used to log errors. func NewEndpointCache(f Factory, logger log.Logger) *EndpointCache { endpointCache := &EndpointCache{ f: f, m: map[string]endpointCloser{}, logger: log.NewContext(logger).With("component", "Endpoint Cache"), } endpointCache.cache.Store(make([]endpoint.Endpoint, 0)) return endpointCache }
func NewDispatcher(ctx context.Context, msgChannel chan *message.Message, loader *Loader) *Dispatcher { d := &Dispatcher{ ctx: ctx, loader: loader, msgChannel: msgChannel, logger: kitlog.NewContext(log.Logger).With("m", "dispatcher"), } go d.dispatch() return d }
func BenchmarkTenWith(b *testing.B) { logger := log.NewNopLogger() lc := log.NewContext(logger).With("k", "v") for i := 1; i < 10; i++ { lc = lc.With("k", "v") } b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { lc.Log("k", "v") } }