github.com/yankunsam/loki/v2@v2.6.3-0.20220817130409-389df5235c27/clients/cmd/promtail/main.go (about) 1 package main 2 3 import ( 4 "flag" 5 "fmt" 6 "os" 7 "reflect" 8 9 // embed time zone data 10 _ "time/tzdata" 11 12 "k8s.io/klog" 13 14 "github.com/go-kit/log/level" 15 "github.com/grafana/dskit/flagext" 16 "github.com/prometheus/client_golang/prometheus" 17 "github.com/prometheus/common/version" 18 "github.com/weaveworks/common/logging" 19 20 "github.com/grafana/loki/clients/pkg/logentry/stages" 21 "github.com/grafana/loki/clients/pkg/promtail" 22 "github.com/grafana/loki/clients/pkg/promtail/client" 23 "github.com/grafana/loki/clients/pkg/promtail/config" 24 25 "github.com/grafana/loki/pkg/util" 26 _ "github.com/grafana/loki/pkg/util/build" 27 "github.com/grafana/loki/pkg/util/cfg" 28 util_log "github.com/grafana/loki/pkg/util/log" 29 ) 30 31 func init() { 32 prometheus.MustRegister(version.NewCollector("promtail")) 33 } 34 35 type Config struct { 36 config.Config `yaml:",inline"` 37 printVersion bool 38 printConfig bool 39 logConfig bool 40 dryRun bool 41 configFile string 42 configExpandEnv bool 43 inspect bool 44 } 45 46 func (c *Config) RegisterFlags(f *flag.FlagSet) { 47 f.BoolVar(&c.printVersion, "version", false, "Print this builds version information") 48 f.BoolVar(&c.printConfig, "print-config-stderr", false, "Dump the entire Loki config object to stderr") 49 f.BoolVar(&c.logConfig, "log-config-reverse-order", false, "Dump the entire Loki config object at Info log "+ 50 "level with the order reversed, reversing the order makes viewing the entries easier in Grafana.") 51 f.BoolVar(&c.dryRun, "dry-run", false, "Start Promtail but print entries instead of sending them to Loki.") 52 f.BoolVar(&c.inspect, "inspect", false, "Allows for detailed inspection of pipeline stages") 53 f.StringVar(&c.configFile, "config.file", "", "yaml file to load") 54 f.BoolVar(&c.configExpandEnv, "config.expand-env", false, "Expands ${var} in config according to the values of the environment variables.") 55 c.Config.RegisterFlags(f) 56 } 57 58 // Clone takes advantage of pass-by-value semantics to return a distinct *Config. 59 // This is primarily used to parse a different flag set without mutating the original *Config. 60 func (c *Config) Clone() flagext.Registerer { 61 return func(c Config) *Config { 62 return &c 63 }(*c) 64 } 65 66 func main() { 67 // Load config, merging config file and CLI flags 68 var config Config 69 if err := cfg.DefaultUnmarshal(&config, os.Args[1:], flag.CommandLine); err != nil { 70 fmt.Println("Unable to parse config:", err) 71 os.Exit(1) 72 } 73 74 // Handle -version CLI flag 75 if config.printVersion { 76 fmt.Println(version.Print("promtail")) 77 os.Exit(0) 78 } 79 80 // Init the logger which will honor the log level set in cfg.Server 81 if reflect.DeepEqual(&config.Config.ServerConfig.Config.LogLevel, &logging.Level{}) { 82 fmt.Println("Invalid log level") 83 os.Exit(1) 84 } 85 util_log.InitLogger(&config.Config.ServerConfig.Config, prometheus.DefaultRegisterer) 86 87 // Use Stderr instead of files for the klog. 88 klog.SetOutput(os.Stderr) 89 90 if config.inspect { 91 stages.Inspect = true 92 } 93 94 // Set the global debug variable in the stages package which is used to conditionally log 95 // debug messages which otherwise cause huge allocations processing log lines for log messages never printed 96 if config.Config.ServerConfig.Config.LogLevel.String() == "debug" { 97 stages.Debug = true 98 } 99 100 if config.printConfig { 101 err := util.PrintConfig(os.Stderr, &config) 102 if err != nil { 103 level.Error(util_log.Logger).Log("msg", "failed to print config to stderr", "err", err.Error()) 104 } 105 } 106 107 if config.logConfig { 108 err := util.LogConfig(&config) 109 if err != nil { 110 level.Error(util_log.Logger).Log("msg", "failed to log config object", "err", err.Error()) 111 } 112 } 113 114 clientMetrics := client.NewMetrics(prometheus.DefaultRegisterer, config.Config.Options.StreamLagLabels) 115 p, err := promtail.New(config.Config, clientMetrics, config.dryRun) 116 if err != nil { 117 level.Error(util_log.Logger).Log("msg", "error creating promtail", "error", err) 118 os.Exit(1) 119 } 120 121 level.Info(util_log.Logger).Log("msg", "Starting Promtail", "version", version.Info()) 122 defer p.Shutdown() 123 124 if err := p.Run(); err != nil { 125 level.Error(util_log.Logger).Log("msg", "error starting promtail", "error", err) 126 os.Exit(1) 127 } 128 }