Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for pushing logs to loki #1576

Merged
merged 24 commits into from
Aug 12, 2020
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
969f9ba
Add support for pushing logs to loki
mstoykov Jul 30, 2020
0a29fc4
Marshal the log message with encoding/json to escape it properly
mstoykov Jul 31, 2020
08ac162
Support for redirecting the loki push and some more debugging info
mstoykov Jul 31, 2020
9ffee17
Add msgMaxSize flag to loki
mstoykov Jul 31, 2020
d93b9f1
Also escape field values as `error` for example has quotes inside
mstoykov Jul 31, 2020
686ea5f
s/RawFormater/RawFormatter/g
mstoykov Jul 31, 2020
325ce6a
Add todo to rename --logformat
mstoykov Jul 31, 2020
ee774b9
Support all logrus log levels
mstoykov Jul 31, 2020
5f39dc2
drop the start method
mstoykov Jul 31, 2020
ad54b40
remove todo
mstoykov Jul 31, 2020
2d0ea19
slighly better/faster cutOff calculation
mstoykov Jul 31, 2020
dd740d6
check that loki.limit > 0
mstoykov Jul 31, 2020
94e9a69
check that loki.msgMaxSize > 0
mstoykov Jul 31, 2020
e983035
just context.Background() - timeout is set elsewhere
mstoykov Jul 31, 2020
5ff3499
fix dropped message
mstoykov Jul 31, 2020
ee51ebb
Just return an error from push instead of fmt.Println
mstoykov Jul 31, 2020
9ab822a
fixes to LokiFromConfigLine
mstoykov Jul 31, 2020
862bd06
Log responses for status code >=400 from loki
mstoykov Jul 31, 2020
abd5d93
Update cmd/root.go
mstoykov Aug 11, 2020
605b7b0
lint fixes
mstoykov Aug 11, 2020
f93c23a
renames
mstoykov Aug 11, 2020
c322ca8
Support for log-output configuration through K6_LOG_OUTPUT env variable
mstoykov Aug 12, 2020
8a30291
fixup! Support for log-output configuration through K6_LOG_OUTPUT env…
mstoykov Aug 12, 2020
18ae5a0
Use cmf.Flags().Changed() instead of getNullString()
mstoykov Aug 12, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 59 additions & 26 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,14 @@
package cmd

import (
"context"
"fmt"
"io"
"log"
"io/ioutil"
stdlog "log"
"os"
"path/filepath"
"strings"
"sync"

"github.com/fatih/color"
Expand All @@ -36,6 +39,7 @@ import (
"github.com/spf13/pflag"

"github.com/loadimpact/k6/lib/consts"
"github.com/loadimpact/k6/log"
)

var BannerColor = color.New(color.FgCyan)
Expand All @@ -58,13 +62,15 @@ var defaultConfigFilePath = defaultConfigFileName // Updated with the user's con
//nolint:gochecknoglobals
var configFilePath = os.Getenv("K6_CONFIG") // Overridden by `-c`/`--config` flag!

//nolint:gochecknoglobals
var (
//TODO: have environment variables for configuring these? hopefully after we move away from global vars though...
verbose bool
quiet bool
noColor bool
logFmt string
address string
// TODO: have environment variables for configuring these? hopefully after we move away from global vars though...
verbose bool
quiet bool
noColor bool
logOutput string
logFmt string
address string
)

// RootCmd represents the base command when called without any subcommands.
Expand All @@ -74,8 +80,13 @@ var RootCmd = &cobra.Command{
Long: BannerColor.Sprintf("\n%s", consts.Banner),
SilenceUsage: true,
SilenceErrors: true,
PersistentPreRun: func(cmd *cobra.Command, args []string) {
setupLoggers(logFmt)
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
logger := logrus.StandardLogger() // don't use the global one to begin with
err := setupLoggers(logger, logFmt, logOutput)
if err != nil {
return err
}

if noColor {
// TODO: figure out something else... currently, with the wrappers
// below, we're stripping any colors from the output after we've
Expand All @@ -92,8 +103,9 @@ var RootCmd = &cobra.Command{
stdout.Writer = colorable.NewNonColorable(os.Stdout)
stderr.Writer = colorable.NewNonColorable(os.Stderr)
}
log.SetOutput(logrus.StandardLogger().Writer())
logrus.Debugf("k6 version: v%s", consts.FullVersion())
stdlog.SetOutput(logger.Writer())
logger.Debugf("k6 version: v%s", consts.FullVersion())
return nil
},
}

Expand All @@ -116,14 +128,16 @@ func Execute() {

func rootCmdPersistentFlagSet() *pflag.FlagSet {
flags := pflag.NewFlagSet("", pflag.ContinueOnError)
//TODO: figure out a better way to handle the CLI flags - global variables are not very testable... :/
// TODO: figure out a better way to handle the CLI flags - global variables are not very testable... :/
flags.BoolVarP(&verbose, "verbose", "v", false, "enable debug logging")
flags.BoolVarP(&quiet, "quiet", "q", false, "disable progress updates")
flags.BoolVar(&noColor, "no-color", false, "disable colored output")
flags.StringVar(&logFmt, "logformat", "", "log output format")
flags.StringVar(&logOutput, "log-output", "stderr",
"change output to which logs go, possible values are stderr,stdout,none,loki[=host:port]")
na-- marked this conversation as resolved.
Show resolved Hide resolved
mstoykov marked this conversation as resolved.
Show resolved Hide resolved
flags.StringVar(&logFmt, "logformat", "", "log output format") // TODO rename to log-format and warn on old usage
flags.StringVarP(&address, "address", "a", "localhost:6565", "address for the api server")

//TODO: Fix... This default value needed, so both CLI flags and environment variables work
// TODO: Fix... This default value needed, so both CLI flags and environment variables work
flags.StringVarP(&configFilePath, "config", "c", configFilePath, "JSON config file")
// And we also need to explicitly set the default value for the usage message here, so things
// like `K6_CONFIG="blah" k6 run -h` don't produce a weird usage message
Expand Down Expand Up @@ -158,29 +172,48 @@ func fprintf(w io.Writer, format string, a ...interface{}) (n int) {
}

// RawFormatter it does nothing with the message just prints it
type RawFormater struct{}
type RawFormatter struct{}

// Format renders a single log entry
func (f RawFormater) Format(entry *logrus.Entry) ([]byte, error) {
func (f RawFormatter) Format(entry *logrus.Entry) ([]byte, error) {
return append([]byte(entry.Message), '\n'), nil
}

func setupLoggers(logFmt string) {
func setupLoggers(logger *logrus.Logger, logFmt string, logOutput string) error {
na-- marked this conversation as resolved.
Show resolved Hide resolved
if verbose {
logrus.SetLevel(logrus.DebugLevel)
logger.SetLevel(logrus.DebugLevel)
}
switch logOutput {
case "stderr":
logger.SetOutput(stderr)
case "stdout":
logger.SetOutput(stdout)
case "none":
logger.SetOutput(ioutil.Discard)
default:
if !strings.HasPrefix(logOutput, "loki") {
return fmt.Errorf("unsupported log output `%s`", logOutput)
}
hook, err := log.LokiFromConfigLine(context.Background(), logOutput) // TODO use some context that we can cancel
if err != nil {
return err
}
logger.AddHook(hook)
logger.SetOutput(ioutil.Discard) // don't output to anywhere else
logFmt = "raw"
noColor = true // disable color
}
logrus.SetOutput(stderr)

switch logFmt {
case "raw":
logrus.SetFormatter(&RawFormater{})
logrus.Debug("Logger format: RAW")
logger.SetFormatter(&RawFormatter{})
logger.Debug("Logger format: RAW")
case "json":
logrus.SetFormatter(&logrus.JSONFormatter{})
logrus.Debug("Logger format: JSON")
logger.SetFormatter(&logrus.JSONFormatter{})
logger.Debug("Logger format: JSON")
default:
logrus.SetFormatter(&logrus.TextFormatter{ForceColors: stderrTTY, DisableColors: noColor})
logrus.Debug("Logger format: TEXT")
logger.SetFormatter(&logrus.TextFormatter{ForceColors: stderrTTY, DisableColors: noColor})
logger.Debug("Logger format: TEXT")
}

return nil
}
Loading