Skip to content

Commit

Permalink
Add sources to the report output
Browse files Browse the repository at this point in the history
The diagnose report output now contains information about which
source provides a given configuration value (when that source
is not `default`), and which other sources, if any, also provide
the given configuration value.

This brings the diagnose report output's behaviour regarding
sources in line with that of the Ruby and Elixir integration.
  • Loading branch information
unflxw committed Nov 5, 2021
1 parent 3a3dca3 commit 5ab6e0a
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
bump: "patch"
---

Add information about the sources of each configuration value in the output of the diagnose report.
82 changes: 76 additions & 6 deletions packages/nodejs/src/cli/diagnose.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const path = require("path")
const util = require("util")
const readline = require("readline")
import { HashMap } from "@appsignal/types"
import { AppsignalOptions } from ".."

export class Diagnose {
#diagnose: typeof DiagnoseTool
Expand Down Expand Up @@ -149,12 +150,7 @@ export class Diagnose {

this.print_newline()

console.log(`Configuration`)
Object.keys(data["config"]["options"])
.sort()
.forEach(key => {
console.log(` ${key}: ${format_value(data["config"]["options"][key])}`)
})
this.printConfiguration(data["config"])

this.print_newline()

Expand Down Expand Up @@ -349,6 +345,80 @@ export class Diagnose {
}
}

printConfiguration(
{options, sources}: {
options: { [key: string]: any },
sources: { [source: string]: { [key: string]: any } }
}
) {
console.log(`Configuration`)
Object.keys(options)
.sort()
.forEach(key => {
let keySources = this.configurationKeySources(key, sources)

switch (Object.keys(keySources).length) {
case 0:
if (key == 'log_file_path') {
// The `log_file_path` configuration key is generated after
// the config is read and does not belong to any sources.
// Since it is derived from `log_path`, let's give it the
// same source as `log_path`'s final value.
const logPathSources = Object.keys(
this.configurationKeySources('log_path', sources)
)
// `log_path` has a default value, so it always has at least
// one source. The sources are inserted in the order they are
// processed, so the last one overrides the others.
const logPathSource = logPathSources[logPathSources.length - 1]
keySources[logPathSource] = options[key]
} else {
// This branch should not be executed. But if it does,
// let's pretend this key comes from the default source.
keySources["default"] = options[key]
}
// Intentional absence of `break` so that the value is printed
// by the next `case`.
case 1:
const source = Object.keys(keySources)[0]

let extra = ""
if (source !== "default") {
extra = ` (Loaded from: ${source})`
}

console.log(` ${key}: ${format_value(options[key])}${extra}`)
break;
default:
console.log(` ${key}: ${format_value(options[key])}`)
console.log(` Sources:`)
const maxSourceLength = Object.keys(keySources)
// Adding one to account for the `:` after the source name.
.map(source => source.length + 1)
.reduce((max, source) => Math.max(max, source), 0);

Object.entries(keySources).forEach(([source, value]) => {
source = `${source}:`.padEnd(maxSourceLength, ' ')
console.log(` ${source} ${format_value(value)}`)
})
}
})
}

configurationKeySources(
key: string,
sources: { [source: string]: { [key: string]: any } }
) : { [source: string]: any } {
return Object.entries(sources)
.reduce((keySources, [source, sourceOptions]) => {
if (sourceOptions.hasOwnProperty(key)) {
return {...keySources, [source]: sourceOptions[key]}
} else {
return keySources
}
}, {})
}

print_newline() {
console.log(``)
}
Expand Down

0 comments on commit 5ab6e0a

Please sign in to comment.