Merge pull request #7439 from dokku/7354-log-app-label-alias

Allow specifying a custom app label alias when shipping logs via vector
This commit is contained in:
Jose Diaz-Gonzalez
2025-01-06 23:47:19 -05:00
committed by GitHub
7 changed files with 149 additions and 19 deletions

View File

@@ -233,3 +233,33 @@ dokku logs:set test vector-sink "http://?uri=https%3A//loggerservice.com%3A1234/
```
Please read the [sink documentation](https://vector.dev/docs/reference/configuration/sinks/) for your sink of choice to configure the sink as desired.
##### Configuring the app label
Logs shipped by vector include the label `com.dokku.app-name`, which is an alias for the app name. This can be changed via the `app-label-alias` logs property with the `logs:set` command. Specifying a new alias will reload any running vector container.
```shell
# setting the sink value in quotes is encouraged to avoid
# issues with ampersand encoding in shell commands
dokku logs:set node-js-app app-label-alias "app-name"
```
An alias may be removed by setting an empty value, which will also reload the running vector container.
```shell
dokku logs:set node-js-app app-label-alias
```
Only one alias may be specified on a per-app basis at a given time.
App label aliases can also be specified globally by specifying the `--global` flag to `logs:set` with no app name specified:
```shell
dokku logs:set --global app-label-alias "app-name"
```
As with app-specific label alias settings, the global value may also be cleared by setting no value.
```shell
dokku logs:set --global app-label-alias
```

View File

@@ -257,7 +257,7 @@ func writeVectorConfig() error {
data.Sources[fmt.Sprintf("docker-source:%s", inflectedAppName)] = vectorSource{
Type: "docker_logs",
IncludeLabels: []string{fmt.Sprintf("com.dokku.app-name=%s", appName)},
IncludeLabels: []string{fmt.Sprintf("%s=%s", reportComputedAppLabelAlias(appName), appName)},
}
data.Sinks[fmt.Sprintf("docker-sink:%s", inflectedAppName)] = sink
@@ -272,7 +272,7 @@ func writeVectorConfig() error {
data.Sources["docker-global-source"] = vectorSource{
Type: "docker_logs",
IncludeLabels: []string{"com.dokku.app-name"},
IncludeLabels: []string{reportGlobalAppLabelAlias("global")},
}
data.Sinks["docker-global-sink"] = sink

View File

@@ -10,18 +10,23 @@ import (
// MaxSize is the default max retention size for docker logs
const MaxSize = "10m"
// AppLabelAlias is the property key for the app label alias
const AppLabelAlias = "com.dokku.app-name"
var (
// DefaultProperties is a map of all valid logs properties with corresponding default property values
DefaultProperties = map[string]string{
"max-size": "",
"vector-sink": "",
"app-label-alias": AppLabelAlias,
"max-size": MaxSize,
"vector-sink": "",
}
// GlobalProperties is a map of all valid global logs properties
GlobalProperties = map[string]bool{
"max-size": true,
"vector-image": true,
"vector-sink": true,
"app-label-alias": true,
"max-size": true,
"vector-image": true,
"vector-sink": true,
}
)

View File

@@ -11,12 +11,15 @@ func ReportSingleApp(appName string, format string, infoFlag string) error {
}
flags := map[string]common.ReportFunc{
"--logs-computed-max-size": reportComputedMaxSize,
"--logs-global-max-size": reportGlobalMaxSize,
"--logs-global-vector-sink": reportGlobalVectorSink,
"--logs-max-size": reportMaxSize,
"--logs-vector-global-image": reportVectorGlobalImage,
"--logs-vector-sink": reportVectorSink,
"--logs-computed-app-label-alias": reportComputedAppLabelAlias,
"--logs-computed-max-size": reportComputedMaxSize,
"--logs-global-app-label-alias": reportGlobalAppLabelAlias,
"--logs-global-max-size": reportGlobalMaxSize,
"--logs-global-vector-sink": reportGlobalVectorSink,
"--logs-app-label-alias": reportAppLabelAlias,
"--logs-max-size": reportMaxSize,
"--logs-vector-global-image": reportVectorGlobalImage,
"--logs-vector-sink": reportVectorSink,
}
flagKeys := []string{}
@@ -30,6 +33,23 @@ func ReportSingleApp(appName string, format string, infoFlag string) error {
return common.ReportSingleApp("logs", appName, infoFlag, infoFlags, flagKeys, format, trimPrefix, uppercaseFirstCharacter)
}
func reportComputedAppLabelAlias(appName string) string {
value := reportAppLabelAlias(appName)
if value == "" {
value = reportGlobalAppLabelAlias(appName)
}
return value
}
func reportGlobalAppLabelAlias(appName string) string {
return common.PropertyGetDefault("logs", "--global", "app-label-alias", AppLabelAlias)
}
func reportAppLabelAlias(appName string) string {
return common.PropertyGet("logs", appName, "app-label-alias")
}
func reportComputedMaxSize(appName string) string {
value := reportMaxSize(appName)
if value == "" {

View File

@@ -72,7 +72,13 @@ func CommandSet(appName string, property string, value string) error {
}
common.CommandPropertySet("logs", appName, property, value, DefaultProperties, GlobalProperties)
if property == "vector-sink" {
vectorProperties := map[string]bool{
"app-label-alias": true,
"vector-sink": true,
}
if _, ok := vectorProperties[property]; ok {
common.LogVerboseQuiet(fmt.Sprintf("Writing updated vector config to %s", filepath.Join(common.GetDataDirectory("logs"), "vector.json")))
return writeVectorConfig()
}

View File

@@ -3,6 +3,7 @@
load test_helper
setup() {
rm "${BATS_PARENT_TMPNAME}.skip" || true
global_setup
}
@@ -53,7 +54,7 @@ teardown() {
echo "status: $status"
assert_failure
assert_output_contains "$TEST_APP logs information" 0
assert_output_contains "Invalid flag passed, valid flags: --logs-computed-max-size, --logs-global-max-size, --logs-global-vector-sink, --logs-max-size, --logs-vector-global-image, --logs-vector-sink"
assert_output_contains "Invalid flag passed, valid flags: --logs-app-label-alias, --logs-computed-app-label-alias, --logs-computed-max-size, --logs-global-app-label-alias, --logs-global-max-size, --logs-global-vector-sink, --logs-max-size, --logs-vector-global-image, --logs-vector-sink"
run /bin/bash -c "dokku logs:report $TEST_APP --logs-vector-sink 2>&1"
echo "output: $output"
@@ -98,13 +99,13 @@ teardown() {
echo "output: $output"
echo "status: $status"
assert_failure
assert_output_contains "Invalid property specified, valid properties include: max-size, vector-image, vector-sink"
assert_output_contains "Invalid property specified, valid properties include: app-label-alias, max-size, vector-image, vector-sink"
run /bin/bash -c "dokku logs:set $TEST_APP invalid value" 2>&1
echo "output: $output"
echo "status: $status"
assert_failure
assert_output_contains "Invalid property specified, valid properties include: max-size, vector-image, vector-sink"
assert_output_contains "Invalid property specified, valid properties include: app-label-alias, max-size, vector-image, vector-sink"
}
@test "(logs) logs:set app" {
@@ -281,7 +282,6 @@ teardown() {
echo "status: $status"
assert_success
assert_output "2932JSDJ+KSDSDJ"
}
@test "(logs) logs:set global" {
@@ -415,7 +415,75 @@ teardown() {
assert_output "10m"
}
@test "(logs) logs:set max-size with alternate log-driver daemon " {
@test "(logs) logs:set app-label-alias" {
run create_app
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku logs:set $TEST_APP vector-sink console://?encoding[codec]=json" 2>&1
echo "output: $output"
echo "status: $status"
assert_success
assert_output_contains "Setting vector-sink"
assert_output_contains "Writing updated vector config to /var/lib/dokku/data/logs/vector.json"
run /bin/bash -c "dokku logs:set --global app-label-alias" 2>&1
echo "output: $output"
echo "status: $status"
assert_success
assert_output_contains "Unsetting app-label-alias"
assert_output_contains "Writing updated vector config to /var/lib/dokku/data/logs/vector.json"
run /bin/bash -c "jq -r '.sources[\"docker-source:$TEST_APP\"].include_labels[0]' /var/lib/dokku/data/logs/vector.json"
echo "output: $output"
echo "status: $status"
assert_success
assert_output "com.dokku.app-name=$TEST_APP"
run /bin/bash -c "dokku logs:set --global app-label-alias global-alt-name" 2>&1
echo "output: $output"
echo "status: $status"
assert_success
assert_output_contains "Writing updated vector config to /var/lib/dokku/data/logs/vector.json"
run /bin/bash -c "dokku logs:report $TEST_APP --logs-computed-app-label-alias" 2>&1
echo "output: $output"
echo "status: $status"
assert_success
assert_output_contains "global-alt-name"
run /bin/bash -c "cat /var/lib/dokku/data/logs/vector.json"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "jq -r '.sources[\"docker-source:$TEST_APP\"].include_labels[0]' /var/lib/dokku/data/logs/vector.json"
echo "output: $output"
echo "status: $status"
assert_success
assert_output "global-alt-name=$TEST_APP"
run /bin/bash -c "dokku logs:set --global app-label-alias alt-name" 2>&1
echo "output: $output"
echo "status: $status"
assert_success
assert_output_contains "Writing updated vector config to /var/lib/dokku/data/logs/vector.json"
run /bin/bash -c "dokku logs:report $TEST_APP --logs-computed-app-label-alias" 2>&1
echo "output: $output"
echo "status: $status"
assert_success
assert_output_contains "alt-name"
run /bin/bash -c "jq -r '.sources[\"docker-source:$TEST_APP\"].include_labels[0]' /var/lib/dokku/data/logs/vector.json"
echo "output: $output"
echo "status: $status"
assert_success
assert_output "alt-name=$TEST_APP"
}
@test "(logs) logs:set max-size with alternate log-driver daemon" {
if [[ "$REMOTE_CONTAINERS" == "true" ]]; then
skip "skipping due non-existent docker service in remote dev container"
fi

View File

@@ -31,6 +31,7 @@ global_setup() {
global_teardown() {
[[ -n "$BATS_TEST_COMPLETED" ]] || touch "${BATS_PARENT_TMPNAME}.skip"
rm "${BATS_PARENT_TMPNAME}.skip" || true
cleanup_apps
cleanup_containers
}