From 43d6a2ad94b64dcbbbae56a4e430f9a95f69ff01 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Mon, 4 Jan 2021 01:11:49 -0500 Subject: [PATCH] feat: add ability to set a global vector sink --- docs/deployment/logs.md | 20 ++++++++++++++++++-- plugins/logs/functions.go | 18 ++++++++++++++++++ plugins/logs/logs.go | 4 +++- plugins/logs/report.go | 7 ++++++- plugins/logs/src/subcommands/subcommands.go | 6 ++++++ 5 files changed, 51 insertions(+), 4 deletions(-) diff --git a/docs/deployment/logs.md b/docs/deployment/logs.md index 05d2797c7..df7998894 100644 --- a/docs/deployment/logs.md +++ b/docs/deployment/logs.md @@ -4,7 +4,7 @@ logs [-h] [-t] [-n num] [-q] [-p process] # Display recent log output logs:failed [--all|] # Shows the last failed deploy logs logs:report [] [] # Displays a logs report for one or more apps -logs:set # Set or clear a logs property for an app +logs:set [--global|] # Set or clear a logs property for an app logs:vector-logs # Tail the logs of the vector container logs:vector-start # Start the vector logging container logs:vector-stop # Stop the vector logging container @@ -101,7 +101,9 @@ The `vector` container will be stopped and removed from the system. If the conta #### Configuring a log sink -Vector uses the concept of log "sinks" to send logs to a given endpoint. Log sinks may be configured on a per-app basis by specifying a `sink` in DSN form with the `logs:set` command. Specifying a sink value will reload any running vector container. +> If no sinks are specified, the vector container will exit. + +Vector uses the concept of log "sinks" to send logs to a given endpoint. Log sinks may be configured globally or on a per-app basis by specifying a `sink` in DSN form with the `logs:set` command. Specifying a sink value will reload any running vector container. ```shell # setting the sink value in quotes is encouraged to avoid @@ -117,6 +119,20 @@ dokku logs:set node-js-app sink Only one sink may be specified on a per-app basis at a given time. +Log sinks can also be specified globally by specifying the `--global` flag to `logs:set` with no app name specified: + +```shell +dokku logs:set --global sink "console://?encoding[codec]=json" +``` + +As with app-specific sink settings, the global value may also be cleared by setting no value. + +```shell +dokku logs:set --global sink +``` + +If no sink is specified, the vector container may exit prematurely. + ##### Log Sink DSN Format The DSN form of a sink is as follows: diff --git a/plugins/logs/functions.go b/plugins/logs/functions.go index 35856b520..99c1db2c1 100644 --- a/plugins/logs/functions.go +++ b/plugins/logs/functions.go @@ -120,6 +120,9 @@ func valueToConfig(appName string, value string) (vectorSink, error) { t := fmt.Sprintf("type=%s", u.Scheme) i := fmt.Sprintf("inputs[]=docker-source:%s", appName) + if appName == "--global" { + i = "inputs[]=docker-global-source" + } initialQuery := fmt.Sprintf("%s&%s", t, i) query := u.RawQuery if query == "" { @@ -171,6 +174,21 @@ func writeVectorConfig() error { data.Sinks[fmt.Sprintf("docker-sink:%s", appName)] = sink } + value := common.PropertyGet("logs", "--global", "vector-sink") + if value != "" { + sink, err := valueToConfig("--global", value) + if err != nil { + return err + } + + data.Sources["docker-global-source"] = vectorSource{ + Type: "docker_logs", + IncludeLabels: []string{"com.dokku.app-name"}, + } + + data.Sinks["docker-global-sink"] = sink + } + b, err := json.MarshalIndent(data, "", " ") if err != nil { return err diff --git a/plugins/logs/logs.go b/plugins/logs/logs.go index 2ad2a1cec..c966ba25a 100644 --- a/plugins/logs/logs.go +++ b/plugins/logs/logs.go @@ -13,7 +13,9 @@ var ( } // GlobalProperties is a map of all valid global logs properties - GlobalProperties = map[string]bool{} + GlobalProperties = map[string]bool{ + "vector-sink": true, + } ) const VectorImage = "timberio/vector:0.11.X-debian" diff --git a/plugins/logs/report.go b/plugins/logs/report.go index c887a5073..1234e6e55 100644 --- a/plugins/logs/report.go +++ b/plugins/logs/report.go @@ -11,7 +11,8 @@ func ReportSingleApp(appName, infoFlag string) error { } flags := map[string]common.ReportFunc{ - "--logs-vector-sink": reportVectorSink, + "--logs-vector-sink": reportVectorSink, + "--logs-global-vector-sink": reportGlobalVectorSink, } trimPrefix := false @@ -23,3 +24,7 @@ func ReportSingleApp(appName, infoFlag string) error { func reportVectorSink(appName string) string { return common.PropertyGet("logs", appName, "vector-sink") } + +func reportGlobalVectorSink(appName string) string { + return common.PropertyGet("logs", "--global", "vector-sink") +} diff --git a/plugins/logs/src/subcommands/subcommands.go b/plugins/logs/src/subcommands/subcommands.go index bcadf8335..b10ce4912 100644 --- a/plugins/logs/src/subcommands/subcommands.go +++ b/plugins/logs/src/subcommands/subcommands.go @@ -34,10 +34,16 @@ func main() { } case "set": args := flag.NewFlagSet("logs:set", flag.ExitOnError) + global := args.Bool("global", false, "--global: set a global property") args.Parse(os.Args[2:]) appName := args.Arg(0) property := args.Arg(1) value := args.Arg(2) + if *global { + appName = "--global" + property = args.Arg(0) + value = args.Arg(1) + } err = logs.CommandSet(appName, property, value) case "vector-logs": args := flag.NewFlagSet("logs:vector-logs", flag.ExitOnError)