Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
14 changes: 7 additions & 7 deletions cmd/pint/tests/0073_lint_k8s.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,19 @@ level=INFO msg="Finding all rules to check" paths=["rules"]
level=INFO msg="Checking Prometheus rules" entries=4 workers=10 online=true
Bug: required annotation not set (alerts/annotation)
---> rules/1.yml:22-23 -> `Example_High_Restart_Rate` [+1 duplicates]
23 | expr: sum(rate(kube_pod_container_status_restarts_total{namespace="example-app"}[5m])) > ( 3/60 )
^^^ `summary` annotation is required.
23 | expr: sum(rate(kube_pod_container_status_restarts_total{namespace="example-app"}[5m])) > ( 3/60 )
^^^ `summary` annotation is required.

Bug: required label not set (rule/label)
---> rules/1.yml:22-23 -> `Example_High_Restart_Rate` [+1 duplicates]
23 | expr: sum(rate(kube_pod_container_status_restarts_total{namespace="example-app"}[5m])) > ( 3/60 )
^^^ `priority` label is required.
23 | expr: sum(rate(kube_pod_container_status_restarts_total{namespace="example-app"}[5m])) > ( 3/60 )
^^^ `priority` label is required.

Fatal: PromQL syntax error (promql/syntax)
---> rules/1.yml:25 -> `Invalid Query`
25 | expr: sum(rate(kube_pod_container_status_restarts_total{namespace="example-app"}[5m]) / x
^
unclosed left parenthesis
25 | expr: sum(rate(kube_pod_container_status_restarts_total{namespace="example-app"}[5m]) / x
^
unclosed left parenthesis

Fatal: This rule is not a valid Prometheus rule: `duplicated expr key`. (yaml/parse)
---> rules/1.yml:28
Expand Down
44 changes: 22 additions & 22 deletions cmd/pint/tests/0209_multidoc_yaml.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,36 +8,36 @@ level=INFO msg="Finding all rules to check" paths=["rules"]
level=INFO msg="Checking Prometheus rules" entries=9 workers=10 online=true
Warning: unsafe division in aggregation (promql/nan)
---> rules/1.yaml:119-128 -> `Thanos_Rule_High_Rule_Evaluation_Failures`
119 | expr: |2-
119 | expr: |2-
| [...]
123 | by (job,kubernetes_name,pod, pod_app, pod_component)
124 | /
125 | sum(... / rate(prometheus_rule_group_last_duration_seconds{kubernetes_namespace="thanos", pod_app="ruler-core", pod_component="ruler"}[2m]))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This aggregation can return NaN or Inf if any series for `prometheus_rule_group_last_duration_seconds{kubernetes_namespace="thanos", pod_app="ruler-core",
pod_component="ruler"}` evaluates to zero.
126 | by (job,kubernetes_name,pod, pod_app, pod_component)
127 | * 100 > 5
128 | )
123 | by (job,kubernetes_name,pod, pod_app, pod_component)
124 | /
125 | sum(... / rate(prometheus_rule_group_last_duration_seconds{kubernetes_namespace="thanos", pod_app="ruler-core", pod_component="ruler"}[2m]))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This aggregation can return NaN or Inf if any series for `prometheus_rule_group_last_duration_seconds{kubernetes_namespace="thanos", pod_app="ruler-core",
pod_component="ruler"}` evaluates to zero.
126 | by (job,kubernetes_name,pod, pod_app, pod_component)
127 | * 100 > 5
128 | )

Warning: unsafe division in aggregation (promql/nan)
---> rules/1.yaml:119-128 -> `Thanos_Rule_High_Rule_Evaluation_Failures`
119 | expr: |2-
120 |
121 | (
122 | sum(... / rate(prometheus_rule_group_last_duration_seconds{kubernetes_namespace="thanos", pod_app="ruler-core", pod_component="ruler"}[2m]))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This aggregation can return NaN or Inf if any series for `prometheus_rule_group_last_duration_seconds{kubernetes_namespace="thanos", pod_app="ruler-core",
pod_component="ruler"}` evaluates to zero.
123 | by (job,kubernetes_name,pod, pod_app, pod_component)
124 | /
119 | expr: |2-
120 |
121 | (
122 | sum(... / rate(prometheus_rule_group_last_duration_seconds{kubernetes_namespace="thanos", pod_app="ruler-core", pod_component="ruler"}[2m]))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This aggregation can return NaN or Inf if any series for `prometheus_rule_group_last_duration_seconds{kubernetes_namespace="thanos", pod_app="ruler-core",
pod_component="ruler"}` evaluates to zero.
123 | by (job,kubernetes_name,pod, pod_app, pod_component)
124 | /
| [...]
128 | )
128 | )

Warning: required annotation not set (alerts/annotation)
---> rules/1.yaml:143-150 -> `Thanos_Rule_Config_Reload_Failed`
150 | description: Thanos Ruler has not been able to reload its configuration.
^^^ `summary` annotation is required.
150 | description: Thanos Ruler has not been able to reload its configuration.
^^^ `summary` annotation is required.

level=INFO msg="Problems found" Warning=3
-- .pint.hcl --
Expand Down
53 changes: 40 additions & 13 deletions internal/diags/problems.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,28 @@ func InjectDiagnostics(content string, d []Diagnostic, color output.Color) strin

contentLines := strings.Split(content, "\n")

// Minimum leading-space indent across all visible lines.
// gapIndent aligns gap markers, minIndent controls stripping
// (only when the indent is large enough to be worth it).
gapIndent := -1
for _, lineNum := range lines {
if lineNum < 1 || lineNum > len(contentLines) {
continue
}
if trimmed := strings.TrimLeft(contentLines[lineNum-1], " "); len(trimmed) > 0 {
indent := len(contentLines[lineNum-1]) - len(trimmed)
if gapIndent < 0 || indent < gapIndent {
gapIndent = indent
}
}
}
gapIndent = max(0, gapIndent)
minIndent := 0
if gapIndent > 10 {
minIndent = gapIndent
}

var lastWriteLine int
minIndent := -1
for lineIndex, line := range contentLines {

if lineIndex+1 > lastLine {
Expand All @@ -234,6 +254,13 @@ func InjectDiagnostics(content string, d []Diagnostic, color output.Color) strin
trim := trimLine(line, diags, diagPositions, lineIndex+1)
line = trim.line

// Strip common leading whitespace so deeply indented YAML
// expressions don't push content off-screen.
lineStrip := minIndent
if lineStrip > 0 && len(line) >= lineStrip {
line = line[lineStrip:]
}

prefix := fmt.Sprintf(nrFmt+" | ", lineIndex+1)

// Print a gap marker when lines were skipped between the previous
Expand All @@ -243,6 +270,9 @@ func InjectDiagnostics(content string, d []Diagnostic, color output.Color) strin
if lastWriteLine > 0 && lineIndex+1-lastWriteLine > 1 {
skipped := lineIndex + 1 - lastWriteLine - 1
skippedLine := contentLines[lastWriteLine]
if lineStrip > 0 && len(skippedLine) >= lineStrip {
skippedLine = skippedLine[lineStrip:]
}
if skipped == 1 && len(strings.TrimSpace(skippedLine)) < 10 {
buf.WriteString(output.MaybeColor(
output.White, color == output.None,
Expand All @@ -253,31 +283,28 @@ func InjectDiagnostics(content string, d []Diagnostic, color output.Color) strin
} else {
buf.WriteString(output.MaybeColor(output.White, color == output.None, strings.Repeat(" ", digits)))
buf.WriteString(" | ")
if minIndent > 0 {
buf.WriteString(strings.Repeat(" ", minIndent))
if gapIndent > 0 {
buf.WriteString(strings.Repeat(" ", gapIndent))
}
buf.WriteString("[...]\n")
}
}
lastWriteLine = lineIndex + 1

if trimmed := strings.TrimLeft(line, " "); len(trimmed) > 0 {
indent := len(line) - len(trimmed)
if minIndent < 0 || indent < minIndent {
minIndent = indent
}
}

buf.WriteString(output.MaybeColor(output.White, color == output.None, prefix))
for i, ok := range needsNextLine {
if ok {
nextLine[i].WriteString(strings.Repeat(" ", digits+3))
}
}

// Translate displayed column indices back to original columns
// so caret positions still line up after stripping.
colShift := lineStrip
for columnIndex, r := range line {
buf.WriteRune(r)

origCol := columnIndex + 1 + colShift
for i, ok := range needsNextLine {
if !ok {
continue
Expand All @@ -286,8 +313,8 @@ func InjectDiagnostics(content string, d []Diagnostic, color output.Color) strin
if pos.Line != lineIndex+1 {
continue
}
before := pos.FirstColumn > columnIndex+1
inside := pos.FirstColumn <= columnIndex+1 && pos.LastColumn >= columnIndex+1
before := pos.FirstColumn > origCol
inside := pos.FirstColumn <= origCol && pos.LastColumn >= origCol
switch {
case before:
nextLine[i].WriteRune(' ')
Expand All @@ -314,7 +341,7 @@ func InjectDiagnostics(content string, d []Diagnostic, color output.Color) strin
indent = 0
for _, pos := range diagPositions[i] {
if pos.Line == lineIndex+1 && pos.FirstColumn > 0 {
indent = digits + 3 + pos.FirstColumn - 1
indent = digits + 3 + pos.FirstColumn - 1 - colShift
break
}
}
Expand Down
Loading