prometheus icon indicating copy to clipboard operation
prometheus copied to clipboard

Rule formatting tool.

Open juliusv opened this issue 12 years ago • 41 comments

Like "gofmt" for Go, we ought to have a "promfmt" for Prometheus since we have a syntax tree. The idea being that the system produces uniform style that minimizes deviation and learning curve.

Update after we have totally moved to YAML rule files: In addition to formatting the PromQL expressions, we also want to format the YAML files to have a fixed structure, while preserving comments for both PromQL expressions and the YAML file.

juliusv avatar Jan 04 '13 19:01 juliusv

:+1: * :100:

grobie avatar Jun 23 '15 22:06 grobie

Yep, that'd be great. Preserving comments is the biggest (and basically only) problem. And agreement on how to split expressions over multiple lines.

fabxc avatar Jun 24 '15 07:06 fabxc

Aren't we in the middle of adding this to promtool?

brian-brazil avatar Jul 16 '16 00:07 brian-brazil

Related: https://github.com/prometheus/prometheus/pull/1779

mattbostock avatar Oct 03 '16 19:10 mattbostock

Some observations:

  • With the 2.x rule format (YAML embedding PromQL), we want this to act on YAML files, too.
  • It should preserve both comments in YAML and in PromQL.
  • Indentation is crucial (not just line breaks).
  • It has to be seen if certain line breaks in the input should be preserved in the output (cf. how gofmt does it).
  • Wherever a rule is rendered, the same formatting should apply, in particular on the Alerts and Rules tabs of the Prometheus web UI. This implies that the AST needs to keep comments (and possibly certain line breaks, see previous point).

beorn7 avatar Mar 16 '19 22:03 beorn7

It should preserve both comments in YAML

Our current YAML library doesn't do this, but is hoping to "soon".

brian-brazil avatar Mar 17 '19 00:03 brian-brazil

I'd like to include this in my gsoc proposal. @brian-brazil, can you link to the YAML library you're referring to?

geekodour avatar Mar 20 '19 03:03 geekodour

https://github.com/go-yaml/yaml, but I'd scope this to just the PromQL as this stands.

brian-brazil avatar Mar 20 '19 08:03 brian-brazil

@brian-brazil But since the PromQL from rules is always embedded in YAML files, it at least has to preserve YAML comments, right? Otherwise the tool wouldn't be very useful as nobody wants to lose their comments the benefit of formatting.

juliusv avatar Mar 20 '19 19:03 juliusv

That'd be nice, but we can get benefits without that. I'd rather also not depend on something with an unclear timeline for a gsoc project.

brian-brazil avatar Mar 21 '19 00:03 brian-brazil

Let's start with the PromQL part. The YAML part should be almost trivial once the library preserves comments and things like the |2 indentation hint for multiline strings.

beorn7 avatar Mar 21 '19 12:03 beorn7

Ok!

juliusv avatar Mar 21 '19 13:03 juliusv

v3 of the YAML library is out, which should allow for all of this.

brian-brazil avatar Apr 05 '19 18:04 brian-brazil

FYI perfectly readable rule in configuration

(
    kube_job_status_failed > 0
    UNLESS kube_job_status_succeeded > 0
)
* on (namespace, job_name) group_left(maintainer) label_replace(kube_job_labels, "maintainer", "$1", "label_maintainer", "(.*)")
* on (namespace, job_name) group_left(pager) label_replace(kube_job_labels, "pager", "$1", "label_pager", "(.*)")
* on (namespace, job_name) group_left(paging) label_replace(kube_job_labels, "paging", "$1", "label_paging", "(.*)")

VS its garbage representation in the Web UI

(kube_deployment_status_replicas_available
  / kube_deployment_spec_replicas * 100) * on(namespace, deployment) group_left(maintainer)
  label_replace(kube_deployment_labels, "maintainer", "$1", "label_maintainer",
  "(.*)") * on(namespace, deployment) group_left(pager) label_replace(kube_deployment_labels,
  "pager", "$1", "label_pager", "(.*)") * on(namespace,
  deployment) group_left(paging) label_replace(kube_deployment_labels, "paging",
  "$1", "label_paging", "(.*)") < 100

sylr avatar Apr 24 '19 09:04 sylr

@sylr I think you posted some other rule from the web UI. also @beorn7 I am starting to work on this issue.

here's what it shows for me for your rule:

(kube_job_status_failed
  > 0 unless kube_job_status_succeeded > 0) * on(namespace, job_name) group_left(maintainer)
  label_replace(kube_job_labels, "maintainer", "$1", "label_maintainer",
  "(.*)") * on(namespace, job_name) group_left(pager) label_replace(kube_job_labels,
  "pager", "$1", "label_pager", "(.*)") * on(namespace,
  job_name) group_left(paging) label_replace(kube_job_labels, "paging", "$1",
  "label_paging", "(.*)")

geekodour avatar May 15 '19 06:05 geekodour

@geekodour Yes, I mixed up two rules.

sylr avatar May 28 '19 10:05 sylr

since this is still open and added in project ideas for upcoming GSOC (https://github.com/cncf/soc#rule-formatting-tool) i would like to work on the completion of this during GSOC. Any recent update and additional info regarding this would be appreciated @codesome @brian-brazil @juliusv @geekodour @simonpasquier @sylr . From reading the comment and other reference link it seems the next action point is building a formatter for promQL expression with the promQL AST?

haibeey avatar Feb 15 '20 02:02 haibeey

@haibeey There already has been some progress in that direction.

When building such a formatter it probably would be best to start with what is already implemented here and add proper white space and comment handling.

It would be also nice, when such features could be integrated with the upcoming PromQL language server. Inside the language server code a lot of the stuff that is needed to format YAML files is already implemented, and it might make sense to reuse some of it.

slrtbtfs avatar Feb 17 '20 15:02 slrtbtfs

alright! Thanks @slrtbtfs . i will start perusing the links shared ASAP .

haibeey avatar Feb 17 '20 19:02 haibeey

Can I take up this issue? Would love to implement this.

Harkishen-Singh avatar Feb 24 '20 16:02 Harkishen-Singh

It looks like @haibeey is already somehow planning working on this.

roidelapluie avatar Feb 24 '20 16:02 roidelapluie

@roidelapluie I have already implemented a part of it way before. It's just that I had not mentioned here.

Harkishen-Singh avatar Feb 24 '20 17:02 Harkishen-Singh

FYI perfectly readable rule in configuration

(
    kube_job_status_failed > 0
    UNLESS kube_job_status_succeeded > 0
)
* on (namespace, job_name) group_left(maintainer) label_replace(kube_job_labels, "maintainer", "$1", "label_maintainer", "(.*)")
* on (namespace, job_name) group_left(pager) label_replace(kube_job_labels, "pager", "$1", "label_pager", "(.*)")
* on (namespace, job_name) group_left(paging) label_replace(kube_job_labels, "paging", "$1", "label_paging", "(.*)")

VS its garbage representation in the Web UI

(kube_deployment_status_replicas_available
  / kube_deployment_spec_replicas * 100) * on(namespace, deployment) group_left(maintainer)
  label_replace(kube_deployment_labels, "maintainer", "$1", "label_maintainer",
  "(.*)") * on(namespace, deployment) group_left(pager) label_replace(kube_deployment_labels,
  "pager", "$1", "label_pager", "(.*)") * on(namespace,
  deployment) group_left(paging) label_replace(kube_deployment_labels, "paging",
  "$1", "label_paging", "(.*)") < 100

Is this formatting style acceptable? @codesome @juliusv @brian-brazil @beorn7 I'm writing my proposal based on this style.

haibeey avatar Mar 14 '20 12:03 haibeey

The final representation after formatting can be discussed and decided during the GSoC period (maybe even now if any maintainer wants to chime in, but I don't have the bandwidth to review it at the moment). I would suggest (to all GSoC aspirants) to focus on how would you achieve this.

codesome avatar Mar 14 '20 15:03 codesome

https://prometheus.io/docs/practices/rules/ uses the best practices.

brian-brazil avatar Mar 14 '20 17:03 brian-brazil

i wrote a rough prototype to preserve comments by augmenting the goyacc grammar rules a little. commit here https://github.com/haibeey/prometheus/commit/885566786ac20bfd400b2e7db470c92545919690

Rules file recording rule in web ui

haibeey avatar Mar 26 '20 03:03 haibeey

That doesn't look right, the operators aren't on their own line

brian-brazil avatar Mar 26 '20 08:03 brian-brazil

oh yes. that commit doesn't do formmating. it is just to preserve comments in promql expr after evaluation for printing. previous versions ignores all comments after evaluation.

haibeey avatar Mar 26 '20 08:03 haibeey

i wrote a rough prototype to preserve comments by augmenting the goyacc grammar rules a little. commit here [haibeey@8855667]

Putting the comments in the AST seems like a reasonable idea.

I've left some comments about the implementation there.

slrtbtfs avatar Mar 26 '20 10:03 slrtbtfs

https://prometheus.io/docs/practices/rules/ uses the best practices.

Please don't enforce:

sum without (instance)(instance_path:requests:rate5m{job="myjob"})

over

sum(instance_path:requests:rate5m{job="myjob"}) without (instance)

sylr avatar Mar 26 '20 10:03 sylr