func init() { l := &log.Logger{ Handler: text.New(os.Stderr), Level: log.InfoLevel, } logger = log.NewEntry(l) }
func BenchmarkLog4FieldsEntry(b *testing.B) { lh := NewLogHandler(ioutil.Discard) entry := log.NewEntry(nil).WithFields( log.Fields{"FieldA": 1, "FieldB": 2, "FieldC": "fieldc", "D": 200.3}) b.RunParallel(func(pb *testing.PB) { for pb.Next() { lh.HandleLog(entry) } }) }
func main() { if showVersion { printVersion() return } data, err := ioutil.ReadFile(configpath) if err != nil { fmt.Fprintf(os.Stderr, "unable to read config: %v\n", err) os.Exit(1) } config, err := config.Parse(data) if err != nil { fmt.Fprintf(os.Stderr, "config is invalid: %v\n", err) os.Exit(1) } if config.Version != requiredConfigVersion { fmt.Fprintf(os.Stderr, "invalid config version (%d). %d is required\n", config.Version, requiredConfigVersion) os.Exit(1) } output, err := logutils.NewLogFileOutput(config.Logger.Output) if err != nil { fmt.Fprintf(os.Stderr, "unable to open logfile output: %v\n", err) os.Exit(1) } defer output.Close() logger := &log.Logger{ Level: log.Level(config.Logger.Level), Handler: logutils.NewLogHandler(output), } ctx := apexctx.WithLogger(apexctx.Background(), log.NewEntry(logger)) ctx, cancelFunc := context.WithCancel(ctx) defer cancelFunc() switch name := config.Metrics.Type; name { case "graphite": var cfg exportmetrics.GraphiteConfig if err = json.Unmarshal(config.Metrics.Args, &cfg); err != nil { logger.WithError(err).WithField("name", name).Fatal("unable to decode graphite exporter config") } sender, err := exportmetrics.NewGraphiteExporter(&cfg) if err != nil { logger.WithError(err).WithField("name", name).Fatal("unable to create GraphiteExporter") } minimalPeriod := 5 * time.Second period := time.Duration(config.Metrics.Period) if period < minimalPeriod { logger.Warnf("metrics: specified period is too low. Set %s", minimalPeriod) period = minimalPeriod } go func(ctx context.Context, p time.Duration) { for { select { case <-time.After(p): if err := sender.Send(ctx, metrics.DefaultRegistry); err != nil { logger.WithError(err).WithField("name", name).Error("unable to send metrics") } case <-ctx.Done(): return } } }(ctx, period) case "": logger.Warn("metrics: exporter is not specified") default: logger.WithError(err).WithField("exporter", name).Fatal("unknown exporter") } go func() { collect(ctx) for range time.Tick(30 * time.Second) { collect(ctx) } }() checkLimits(ctx) boxTypes := map[string]struct{}{} boxes := isolate.Boxes{} for name, cfg := range config.Isolate { if _, ok := boxTypes[cfg.Type]; ok { logger.WithField("box", name).WithField("type", cfg.Type).Fatal("dublicated box type") } boxCtx := apexctx.WithLogger(ctx, logger.WithField("box", name)) box, err := isolate.ConstructBox(boxCtx, cfg.Type, cfg.Args) if err != nil { logger.WithError(err).WithField("box", name).WithField("type", cfg.Type).Fatal("unable to create box") } boxes[name] = box boxTypes[cfg.Type] = struct{}{} } ctx = context.WithValue(ctx, isolate.BoxesTag, boxes) if config.DebugServer != "" { logger.WithField("endpoint", config.DebugServer).Info("start debug HTTP-server") go func() { logger.WithError(http.ListenAndServe(config.DebugServer, nil)).Error("debug server is listening") }() } var wg sync.WaitGroup for _, endpoint := range config.Endpoints { logger.WithField("endpoint", endpoint).Info("start TCP server") ln, err := net.Listen("tcp", endpoint) if err != nil { logger.WithError(err).WithField("endpoint", endpoint).Fatal("unable to listen to") } defer ln.Close() wg.Add(1) func(ln net.Listener) { defer wg.Done() lnLogger := logger.WithField("listener", ln.Addr()) for { conn, err := ln.Accept() if err != nil { lnLogger.WithError(err).Error("Accept") continue } // TODO: more optimal way connID := fmt.Sprintf("%.4x", md5.Sum([]byte(fmt.Sprintf("%s.%d", conn.RemoteAddr().String(), time.Now().Unix())))) lnLogger.WithFields(log.Fields{"remote.addr": conn.RemoteAddr(), "conn.id": connID}).Info("accepted new connection") connHandler, err := isolate.NewConnectionHandler(context.WithValue(ctx, "conn.id", connID)) if err != nil { lnLogger.WithError(err).Fatal("unable to create connection handler") } go func() { conns.Inc(1) defer conns.Dec(1) connHandler.HandleConn(conn) }() } }(ln) } wg.Wait() }