How to merge labels of two Prometheus queries? [duplicate] - join

I am using the consul exporter to ingest the health and status of my services into Prometheus. I'd like to fire alerts when the status of services and nodes in Consul is critical and then use tags extracted from Consul when routing those alerts.
I understand from this discussion that service tags are likely to be exported as a separate metric, but I'm not sure how to join one series with another so I can leverage the tags with the health status.
For example, the following query:
max(consul_health_service_status{status="critical"}) by (service_name, status,node) == 1
could return:
{node="app-server-02",service_name="app-server",status="critical"} 1
but I'd also like 'env' from this series:
consul_service_tags{node="app-server-02",service_name="app-server",env="prod"} 1
to get joined along node and service_name to pass the following to the Alertmanager as a single series:
{node="app-server-02",service_name="app-server",status="critical",env="prod"} 1
I could then match 'env' in my routing.
Is there any way to do this? It doesn't look to me like any operations or functions give me the ability to group or join like this. As far as I can see, the tags would already need to be labels on the consul_health_service_status metric.

You can use the argument list of group_left to include extra labels from the right operand (parentheses and indents for clarity):
(
max(consul_health_service_status{status="critical"})
by (service_name,status,node) == 1
)
+ on(service_name,node) group_left(env)
(
0 * consul_service_tags
)
The important part here is the operation + on(service_name,node) group_left(env):
the + is "abused" as a join operator (fine since 0 * consul_service_tags always has the value 0)
group_left(env) is the modifier that includes the extra label env from the right (consul_service_tags)

The answer in this question is accurate. I want to also share a clearer explanation on joining two metrics preserving SAME Labels (might not be directly answering the question). In these metrics following label is there.
name (eg: aaa, bbb, ccc)
I have a metric name metric_a, and if this returns no data for some of the labels, I wish to fetch data from metric_b. i.e:
metric_a has values for {name="aaa"} and {name="bbb"}
metric_b has values for {name="ccc"}
I want the output to be for all three name labels. The solution is to use or in Prometheus.
sum by (name) (increase(metric_a[1w]))
or
sum by (name) (increase(metric_b[1w]))
The result of this will have values for {name="aaa"}, {name="bbb"} and {name="ccc"}.

It is a good practice in Prometheus ecosystem to expose additional labels, which can be joined to multiple metrics, via a separate info-like metric as explained in this article. For example, consul_service_tags metric exposes a set of tags, which can be joined to metrics via (service_name, node) labels.
The join is usually performed via on() and group_left() modifiers applied to * operation. The * doesn't modify values for time series on the left side because info-like metrics usually have constant 1 values. The on() modifier is used for limiting the labels used for finding matching time series on the left and the right side of *. The group_left() modifier is used for adding additional labels from time series on the right side of *. See these docs for details.
For example, the following PromQL query adds env label from consul_service_tags metric to consul_health_service_status metric with the same set of (service_name, node) labels:
consul_health_service_status
* on(service_name, node) group_left(env)
consul_service_tags
Additional label filters can be added to consul_health_service_status if needed. For example, the following query returns only time series with status="critical" label:
consul_health_service_status{status="critical"}
* on(service_name, node) group_left(env)
consul_service_tags

Related

Promql query not working "cpu_usage_value or memory_usage_value"

according to prometheus doc :
vector1 or vector2 results in a vector that contains all original elements (label sets + values) of vector1 and additionally all elements of vector2 which do not have matching label sets in vector1
but the above query only returns cpu_usage_value
promql beginner, pardon if understood the doc wrong
The or operator doesn't take into account metric names when searching for time series on the left side of or with labelsets, which are missing in time series on the right side of or. See these docs.
There are the following solutions:
To explicitly mention __name__ label (aka metric name) in the list of labels, which should be taken into account when matching series by their labelsets: foo or on(__name__) bar would return series with both foo and bar names.
To enumerate the needed metric names in series selector regexp: {__name__=~"foo|bar"} returns series with both foo and bar names.
To use union function from MetricsQL: union(foo, bar) returns series with foo and bar names. Note that this solution works only in VictoriaMetrics (Prometheus-like system I work on). It doesn't work in Prometheus :(

Influx QL Variables Integer and Variable Embedding Not working

I was trying to write a simple FluxQL Query in Grafana Dashboard that uses a variable
m1(of type constant)(which contains the name of the measurement)
I created the variable m1 in grafana dashboard variables
m1 = my-measurement
and tried to run the following queries but non of them worked and they either say expression request error or No Data)
i.e
SELECT count("fails") FROM "/^${m1:raw}$/"
SELECT count("fails") FROM "/^${m1}$/"
SELECT count("fails") FROM $m1" (expression request error)
SELECT count("fails") FROM "$m1"
SELECT count("fails") FROM "${m1}"
The only query worked was without dashboard variables
SELECT count("fails") FROM "my-measurement"
How can I use the variables to work for that query.
On the similar ground I tried to make a custom variable(myVar) for which we take integer input values from user and on that basis where clause should work, but same error occurs either no data or expression request error
What I tried was
SELECT count(*) from "my-measurement-2" WHERE ("value" > $myVar)
How should I solve these issues?Please help
You may have a problem with
1.) syntax
SELECT count("fails")
FROM "${m1:raw}"
2.) data
You may correct query syntax, but query can be very inefficient. Query execution may need a lot of time - so it's better to have timefilter, which will use selected dashboard time range (make sure you have some data in that time range)
SELECT count("fails")
FROM "${m1:raw}"
WHERE $timeFilter
3.) Grafana panel configuration
Make sure you are using suitable panel - for query above Stat panel is a good option (that query returns only single value, not timeseries, so time series panel types may have a problem with that).
Generally, use query inspector to see how are variables interpolated - there can be "magic", which is not obvious - e.g. quotes which are added around numeric variables, so then it is string filtering and not numeric filtering on the InfluxDB level.

How to express multiple property set criteria for node selection using gremlin query

Here is my simplified graph schema,
package:
property:
- name: str (indexed)
- version: str (indexed)
I want to query the version using multiple set of property criteria within single query. I can use within for a list of single property, but how to do it for multiple properties?
Consider I have 10 package nodes, (p1,v1, p2,v2, p3,v3,.. p10,v10)
I want to select only nodes which has (p1 with v1, p8 with v8, p10 with v10)
Is there a way to do with single gremlin query?
Something equivalent to SELECT * from package WHERE (name, version) in ((p1,v1),(p8,v8),(p10,v10)).
It's always best to provide some sample data when asking questions about Gremlin. I assume that this is an approximation of what your model is:
g.addV('package').property('name','gremlin').property('version', '1.0').
addV('package').property('name','gremlin').property('version', '2.0').
addV('package').property('name','gremlin').property('version', '3.0').
addV('package').property('name','blueprints').property('version', '1.0').
addV('package').property('name','blueprints').property('version', '2.0').
addV('package').property('name','rexster').property('version', '1.0').
addV('package').property('name','rexster').property('version', '2.0').iterate()
I don't think that there is a way that you can compare pairs of inputs and expect an index hit. You therefore have to do what you normally do in graphs and choose the index to best narrow your results before you filter in memory. I would assume that in your case this would be the "name" property, therefore grab those first then filter the pairs:
gremlin> g.V().has('package','name', within('gremlin','blueprints')).
......1> elementMap().
......2> where(select('name','version').is(within([name:'gremlin',version:'2.0'], [name:'blueprints',version:'2.0'])))
==>[id:3,label:package,name:gremlin,version:2.0]
==>[id:12,label:package,name:blueprints,version:2.0]
this might not be the most "creative" way of doing that,
but I think that the easiest way would be to use or:
g.V().or(
hasLabel('v1').has('prop', 'p1'),
hasLabel('v8').has('prop', 'p8'),
hasLabel('v10').has('prop', 'p10')
)
example: https://gremlify.com/6s

InfluxDB mixing agregation function with non-aggregat fields/values

I have a following issue:
I need to calculate difference between consecutive points where some arbitrary ID is equal. The following:
SELECT difference(value_field) FROM mesurementName WHERE "IdField" = '10'
Works, returns difference between each consecutive point with IdField BUT IdField is lost (only time is propagated to query result). In my case time is not unique (i.e. measurement may contain many points with same timestamp, but different IdField). So I tried:
SELECT difference(value_field), IdField FROM mesurementName WHERE "IdField" = '10'
which yields:
error parsing query: mixing aggregate and non-aggregate queries is not supported!!
My next attempt was using sub-query:
SELECT IdField, diff
FROM (
SELECT
difference(flow_val) as diff
FROM
mesurementA
WHERE "IdField" = '10'
)
Which resulted in always null value in IdField.
I'd like to ask you for help or suggestion how to solve issue. By the way, we are using InfluxDB 1.3, which is not supporting JOIN anymore
If anyone would stuck as I was, then solution is following:
SELECT difference(value_field) FROM mesurementName GROUP BY "IdField"
Above somehow implicitly add "IdField" to result series and is propagated to resulting measurements with INTO clause

How to add multiple labels to a node in Neo4J when using Neo4jImport.bat

I am using Neo4jImport.bat to perform my initial database load. I have a node file that looks like this:
application_id:ID(application_id),:LABEL
2036983247,application_id
2037028183,application_id
I would like to (sometimes) add a second :suspect label to some of these rows. For example:
application_id:ID(application_id),:LABEL
2036983247,"application_id,suspect"
2037028183,application_id
Using the above format, the files will load successfully, however, when I try and query the data using cypher I run into issues. Specifically, the below queries return 0 results:
match (n:application_id {application_id:"2036983247"}) return *
match (n:suspect) return *
Whilst the query against the row with a single label works fine:
match (n:application_id {application_id:"2037028183"}) return *
To make it more confusing, the labels() function seems to correctly show the labels as expected being returned in an array for the app with multiple labels.
According to the import documentation on labels:
LABEL
Read one or more labels from this field. For multiple labels, the values are separated by the array delimiter.
What am I doing wrong?
Each :LABEL column can have multiple labels in them, separated by whatever --array-delimiter specifies (defaults to ';'). Also, as Robert mentioned, multiple :LABEL columns is also supported.
To add additional labels to a node, simply add an additional :LABEL header column for each additional label you wish to add.
application_id:ID(application_id),:LABEL,:LABEL
In the contents of the file, you then delimit your labels with whatever delimiter you are using:
2036983247,application_id,suspect
2037028183,application_id
Unlike properties, it seems that the import tool will allow :LABEL columns to be 'missing' (at least if they're the last column).

Resources