diff --git a/server/events/command/project_context.go b/server/events/command/project_context.go index 139731d96d..540b4abadf 100644 --- a/server/events/command/project_context.go +++ b/server/events/command/project_context.go @@ -98,20 +98,23 @@ type ProjectContext struct { ExecutionOrderGroup int } -// SetScopeTags adds ProjectContext tags to a new returned scope. -func (p ProjectContext) SetScopeTags(scope tally.Scope) tally.Scope { +// SetProjectScopeTags adds ProjectContext tags to a new returned scope. +func (p ProjectContext) SetProjectScopeTags(scope tally.Scope) tally.Scope { v := "" if p.TerraformVersion != nil { v = p.TerraformVersion.String() } - return scope.Tagged(map[string]string{ - "base_repo": p.BaseRepo.FullName, - "pr_number": strconv.Itoa(p.Pull.Num), - "project": p.ProjectName, - "project_path": p.RepoRelDir, - "terraform_version": v, - "workspace": p.Workspace, - }) + + tags := ProjectScopeTags{ + BaseRepo: p.BaseRepo.FullName, + PrNumber: strconv.Itoa(p.Pull.Num), + Project: p.ProjectName, + ProjectPath: p.RepoRelDir, + TerraformVersion: v, + Workspace: p.Workspace, + } + + return scope.Tagged(tags.Loadtags()) } // GetShowResultFileName returns the filename (not the path) to store the tf show result diff --git a/server/events/command/scope_tags.go b/server/events/command/scope_tags.go new file mode 100644 index 0000000000..2f51d86c83 --- /dev/null +++ b/server/events/command/scope_tags.go @@ -0,0 +1,38 @@ +package command + +import ( + "reflect" + "regexp" + "strings" +) + +type ProjectScopeTags struct { + BaseRepo string + PrNumber string + Project string + ProjectPath string + TerraformVersion string + Workspace string +} + +func (s ProjectScopeTags) Loadtags() map[string]string { + tags := make(map[string]string) + + v := reflect.ValueOf(s) + t := v.Type() + + for i := 0; i < v.NumField(); i++ { + tags[toSnakeCase(t.Field(i).Name)] = v.Field(i).String() + } + + return tags +} + +func toSnakeCase(str string) string { + var matchFirstCap = regexp.MustCompile("(.)([A-Z][a-z]+)") + var matchAllCap = regexp.MustCompile("([a-z0-9])([A-Z])") + + snake := matchFirstCap.ReplaceAllString(str, "${1}_${2}") + snake = matchAllCap.ReplaceAllString(snake, "${1}_${2}") + return strings.ToLower(snake) +} diff --git a/server/events/instrumented_project_command_runner.go b/server/events/instrumented_project_command_runner.go index 218fa37082..3fe41b4c9e 100644 --- a/server/events/instrumented_project_command_runner.go +++ b/server/events/instrumented_project_command_runner.go @@ -19,7 +19,8 @@ type InstrumentedProjectCommandRunner struct { } func NewInstrumentedProjectCommandRunner(scope tally.Scope, projectCommandRunner ProjectCommandRunner) *InstrumentedProjectCommandRunner { - scope = scope.SubScope("project") + projectTags := command.ProjectScopeTags{} + scope = scope.Tagged(projectTags.Loadtags()) for _, m := range []string{metrics.ExecutionSuccessMetric, metrics.ExecutionErrorMetric, metrics.ExecutionFailureMetric} { metrics.InitCounter(scope, m) @@ -49,7 +50,7 @@ func (p *InstrumentedProjectCommandRunner) ApprovePolicies(ctx command.ProjectCo func RunAndEmitStats(commandName string, ctx command.ProjectContext, execute func(ctx command.ProjectContext) command.ProjectResult, scope tally.Scope) command.ProjectResult { // ensures we are differentiating between project level command and overall command - scope = ctx.SetScopeTags(scope) + scope = ctx.SetProjectScopeTags(scope) logger := ctx.Log executionTime := scope.Timer(metrics.ExecutionTimeMetric).Start() diff --git a/server/events/project_command_context_builder.go b/server/events/project_command_context_builder.go index 62b9adbf27..d18d2b294f 100644 --- a/server/events/project_command_context_builder.go +++ b/server/events/project_command_context_builder.go @@ -78,7 +78,7 @@ func (cb *CommandScopedStatsProjectCommandContextBuilder) BuildProjectContext( // specifically use the command name in the context instead of the arg // since we can return multiple commands worth of contexts for a given command name arg // to effectively pipeline them. - cmd.Scope = cmd.SetScopeTags(cmd.Scope) + cmd.Scope = cmd.SetProjectScopeTags(cmd.Scope) projectCmds = append(projectCmds, cmd) }