I'm using InfluxDB to configure alert against data collected via node_exporter & prometheus. I use the attached query to validate the usage of CPU (refer image 1)
from(bucket: "prometheus")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r["_field"] == "node_cpu_seconds_total" and r["mode"] == "idle")
|> aggregateWindow(every: 1m, fn: mean, createEmpty: false)
|> derivative(timeColumn: "_time", columns: ["_value"])
|> map(
fn: (r) =>
({
_time: r._time,
node_cpu_seconds_total: r["_value"],
_field: r.cpu,
_value: 100.0 - r._value * 100.0,
}),
)
|> yield()
The output is working as expected. But when i try to configure an alert against the same query via API. It's not working as expected.
API Endpoint: https://ap-southeast-2-1.aws.cloud2.influxdata.com/api/v2/checks
Method: POST
Payload:
{
"id": null,
"type": "threshold",
"status": "active",
"activeStatus": "active",
"name": "API Test",
"query": {
"name": "",
"text": "from(bucket: \"prometheus\") |> range(start: -30m) |> filter(fn: (r) => r[\"_field\"] == \"node_cpu_seconds_total\" and r[\"mode\"] == \"idle\") |> aggregateWindow(every: 1m, fn: mean, createEmpty: false) |> derivative(timeColumn: \"_time\", columns: [\"_value\"]) |> map( fn: (r) => ({_time: r._time, _field: r.cpu,node_cpu_seconds_total: r[\"_value\"], job: r[\"job\"], _value: 100.0 - r._value * 100.0}), ) |> yield()",
"editMode": "builder",
"builderConfig": {
"buckets": [
"prometheus"
],
"tags": [
{
"key": "_measurement",
"values": [
"_all"
],
"aggregateFunctionType": "filter"
},
{
"key": "_field",
"values": [
"_value"
],
"aggregateFunctionType": "filter"
}
],
"functions": [
{
"name": "mean"
}
],
"aggregateWindow": {
"period": "30m",
"fillValues": false
}
},
"hidden": false
},
"orgID": "2f4c02f2aa443cb5",
"labels": [],
"description": "",
"every": "1m",
"offset": "0s",
"statusMessageTemplate": "Check: ${ r._check_name } is: ${ r._level }",
"tags": [],
"thresholds": [
{
"type": "greater",
"value": 3.0,
"level": "INFO"
}
]
}
Observations:
Alert is created on the console
The task created against the alert is not reflecting the query i mentioned. Attached the task code below.
import "influxdata/influxdb/monitor"
import "influxdata/influxdb/schema"
data =
from(bucket: "prometheus")
|> range(start: -1m)
|> filter(fn: (r) => r["_field"] == "node_cpu_seconds_total" and r["mode"] == "idle")
|> aggregateWindow(every: 1m, fn: mean, createEmpty: false)
|> derivative(timeColumn: "_time", columns: ["_value"])
|> map(
fn: (r) =>
({
_time: r._time,
_field: r.cpu,
node_cpu_seconds_total: r["_value"],
job: r["job"],
_value: 100.0 - r._value * 100.0,
}),
)
option task = {name: "API Test", every: 1m, offset: 0s}
check = {_check_id: "0a65e164fceff000", _check_name: "API Test", _type: "threshold", tags: {}}
info = (r) => r["node_cpu_seconds_total"] > 3.0
messageFn = (r) => "Check: ${ r._check_name } is: ${ r._level }"
data |> schema["fieldsAsCols"]() |> monitor["check"](data: check, messageFn: messageFn, info: info)
Output
Related
I have a graph like this
O
|
A
|
B
/ \
C E
/ \
D F
I want to find the path from O to F. node F can contain an attribute call "non-direct". If this attribute is set false, then the path is
O-A-B-E-F
However, if it is set to true, the path is
O-A-B-C-D-C-B-E-F
I.e., the path first has to reach B which is a terminal node and then go back to the common parent between D and F, then walk to F.
How can I create a query to return these two path based on the attribute value?
Since Neo4j will not traverse back over the same relationship, you may need to create relationships in both direction on the branches. So something like this:
In addition, I would add some properties that indicate the toplogy, so for instance add a property on-branch for the nodes C and D.
Then you can run queries like this:
MATCH (f:Thing {name:'F'}), (o:Thing {name:'O'}), (d:Thing {name:'D'})
MATCH p = (o)-[:NEXT*]->(f)
WHERE ANY(node IN nodes(p) WHERE node.`on-branch`) = f.`non-direct`
AND (d IN nodes(p)) = f.`non-direct`
RETURN REDUCE(s='', node IN nodes(p) | s+ ' '+ node.name) AS nodes
The graph I tried this on can be created from this json:
{
"nodes": [
{
"id": 0,
"labels": [
"Thing"
],
"properties": {
"name": "O",
"on-branch": false
}
},
{
"id": 1,
"labels": [
"Thing"
],
"properties": {
"name": "A",
"on-branch": false
}
},
{
"id": 2,
"labels": [
"Thing"
],
"properties": {
"name": "B",
"on-branch": false
}
},
{
"id": 3,
"labels": [
"Thing"
],
"properties": {
"name": "C",
"on-branch": true
}
},
{
"id": 4,
"labels": [
"Thing"
],
"properties": {
"name": "D",
"on-branch": true
}
},
{
"id": 5,
"labels": [
"Thing"
],
"properties": {
"name": "E",
"on-branch": false
}
},
{
"id": 6,
"labels": [
"Thing"
],
"properties": {
"name": "F",
"non-direct": false,
"on-branch": false
}
}
],
"relations": [
{
"id": 0,
"source": 0,
"target": 1,
"type": "NEXT",
"properties": {}
},
{
"id": 1,
"source": 1,
"target": 2,
"type": "NEXT",
"properties": {}
},
{
"id": 2,
"source": 3,
"target": 2,
"type": "NEXT",
"properties": {}
},
{
"id": 3,
"source": 2,
"target": 3,
"type": "NEXT",
"properties": {}
},
{
"id": 4,
"source": 4,
"target": 3,
"type": "NEXT",
"properties": {}
},
{
"id": 5,
"source": 3,
"target": 4,
"type": "NEXT",
"properties": {}
},
{
"id": 6,
"source": 2,
"target": 5,
"type": "NEXT",
"properties": {}
},
{
"id": 7,
"source": 5,
"target": 6,
"type": "NEXT",
"properties": {}
}
]
}
The json above can be loaded with this cypher (in Neo4j with apoc):
CALL apoc.load.json([ url to the json]) YIELD value AS v
UNWIND v.nodes AS node
CALL apoc.merge.node(
node.labels,
{ _tempID : node.id},
node.properties,
{}
) YIELD node AS n
WITH DISTINCT v
UNWIND v.relations AS rel
MATCH (from {_tempID: rel.source})
MATCH (to {_tempID: rel.target})
CALL apoc.merge.relationship(
from,
rel.type,
{},
rel.properties,
to,
{}
) YIELD rel AS r
WITH DISTINCT v
MATCH (n) WHERE EXISTS(n._tempID)
REMOVE n._tempID
I have this javascript code to draw an amchart stock, just the PeriodSelector part:
var periodSelectorAjax = new AmCharts.PeriodSelector();
periodSelectorAjax.periods = [
{period: "F1", label: "Phase 1"},
{period: "F2", label: "Phase 2"},
{period: "F3", label: "Phase 3"},
{period: "MAX", selected: true, label: "MAX"}
];
I need to intercept when user click on period to reload the graph, I see that I can do it with this, from here:
var chart = AmCharts.makeChart( "chartdiv", {
"type": "stock",
// ...
"periodSelector": {
"position": "left",
"periods": [ {
"period": "MM",
"selected": true,
"count": 1,
"label": "1 month"
}, {
"period": "YYYY",
"count": 1,
"label": "1 year"
}, {
"period": "YTD",
"label": "YTD"
}, {
"period": "MAX",
"label": "MAX"
} ],
"listeners": [ {
"event": "changed",
"method": function( event ) {
if ( event.predefinedPeriod !== undefined ) {
console.log( event.predefinedPeriod, event.count );
}
}
} ]
},
// ...
} );
But I don't know how to put the last listeners part and use it with my code.
thanks
You can either use the addListener method or just set the listeners array directly on your periodSelectorAjax variable.
addListener example:
periodSelectorAjax.addListener("changed", function(event) {
// your code here
});
listeners property example:
periodSelectorAjax.listeners = [{
"event": "changed",
"method": function(event) {
// ...
}
}]
users,
I am trying to receive all paths (e.g., length < 3) , print the node titles, but also the relationship type.
Using:
MATCH (p0:Page {title:'New Zealand'}), (p1:Page {title:'Kiwi'}), p = (p0)-[r*..2]-(p1)
RETURN p AS path
Prints the paths, but the relationship is represented as {}
As I am using *..2,
`RETURN p,type(r)'
is not working(Type mismatch: expected Relationship but was Collection)
I can use a workaround like:
MATCH
(p0:Page {title:'New Zealand'}),
(p1:Page {title:'Kiwi'}),
p = (p0)-[r]-(p3)-[r1]-(p1)
RETURN p0,type(r),p3,type(r1)
but with increasing pathlength, I would have executed a query for each pathlength.
I tried:
MATCH
(p0:Page {title:'New Zealand'}),
(p1:Page {title:'Kiwi'}),
p = (p0)-[r*..2]-(p1) FOREACH(r in p | RETURN p,p0,type(r),p1)
-> expected Collection but was Path
Does anyone have hint?
Additional information JSON output(snippet) from Neo4j interface:
{
"results": [
{
"columns": [
"p",
"rels(p)",
"nodes(p)"
],
"data": [
{
"row": [
[
{
"title": "New Zealand"
},
{},
{
"title": "Category:Birds of New Zealand"
},
{},
{
"title": "Kiwi"
}
],
[
{},
{}
],
[
{
"title": "New Zealand"
},
{
"title": "Category:Birds of New Zealand"
},
{
"title": "Kiwi"
}
]
],
"graph": {
"nodes": [
{
"id": "11120",
"labels": [
"Page"
],
"properties": {
"title": "Kiwi"
}
},
{
"id": "1942858",
"labels": [
"Page"
],
"properties": {
"title": "New Zealand"
}
},
{
"id": "11994493",
"labels": [
"Category"
],
"properties": {
"title": "Category:Birds of New Zealand"
}
}
],
"relationships": [
{
"id": "1070940",
"type": "To_Category",
"startNode": "11120",
"endNode": "11994493",
"properties": {}
},
You can simply use extract for extracting the type of relationships inside the path.
Based on the simple movie graph on http://console.neo4j.org :
MATCH p=(:Crew { name:"Neo" })-[r*3]-()
RETURN p, extract(x IN rels(p)| type(x)) AS types
Your query would then be :
MATCH (p0:Page {title:'New Zealand'}), (p1:Page {title:'Kiwi'}),
p=(p0)-[r*..2]-(p1)
RETURN p, extract (rel in rels(p) | type(rel) ) as types
This will return you a collection of types :
[LOVE, KNOWS, KNOWS]
So you can have duplicates. If you need to de-duplicate them, use UNWIND and distinct :
MATCH (p0:Page {title:'New Zealand'}), (p1:Page {title:'Kiwi'}),
p=(p0)-[r*..2]-(p1)
WITH p, extract (rel in rels(p) | type(rel) ) as types
UNWIND types as t
RETURN p, collect(distinct t) as types
UPDATE
I wasn't so happy with the last one, so here an easier way :
MATCH (p0:Page {title:'New Zealand'}), (p1:Page {title:'Kiwi'}),
p=(p0)-[r*..2]-(p1)
UNWIND rels(p) as rel
RETURN p, collect(distinct type(rel)) as types
Does using the rels function help you?
MATCH (p0:Page {title:'New Zealand'}), (p1:Page {title:'Kiwi'}), p = (p0)-[r*..2]-(p1)
RETURN p, rels(p), nodes(p)
I am trying to get the relationship type of a very simple Cypher query, like the following
MATCH (n)-[r]-(m) RETURN n, r, m;
Unfortunately this return an empty object for r. This is troublesome since I can't distinguish between the different types of relationships. I can monkey patch this by adding a property like [r:KNOWS {type:'KNOWS'}] but I am wondering if there isn't a direct way to get the relationship type.
I even followed the official Neo4J tutorial (as described below), demonstrating the problem.
Graph Setup:
create (_0 {`age`:55, `happy`:"Yes!", `name`:"A"})
create (_1 {`name`:"B"})
create _0-[:`KNOWS`]->_1
create _0-[:`BLOCKS`]->_1
Query:
MATCH p=(a { name: "A" })-[r]->(b)
RETURN *
JSON RESPONSE BODY:
{
"results": [
{
"columns": [
"a",
"b",
"p",
"r"
],
"data": [
{
"row": [
{
"name": "A",
"age": 55,
"happy": "Yes!"
},
{
"name": "B"
},
[
{
"name": "A",
"age": 55,
"happy": "Yes!"
},
{},
{
"name": "B"
}
],
{}
]
},
{
"row": [
{
"name": "A",
"age": 55,
"happy": "Yes!"
},
{
"name": "B"
},
[
{
"name": "A",
"age": 55,
"happy": "Yes!"
},
{},
{
"name": "B"
}
],
{}
]
}
]
}
],
"errors": []
}
As you can see, I get an empty object for r, which makes it impossible to distinguish between the relationships.
NOTE: I am running Neo4J v.2.2.2
Use the type() function.
MATCH (n)-[r]-(m) RETURN type(r);
Added distinct.
MATCH (n)-[r]-(m) RETURN distinct type(r);
I follow this answer for creating collapsible set. now I want to create nested collapsible set. I have a json like:
[
{
"sid": "26",
"tour_name": "4",
"day": "2",
"time": "16:00",
"main_location": "Madurai",
"sub_location": "Mahal",
"site_link": "www.maduraimahal.com",
"description": "test"
},
{
"sid": "25",
"tour_name": "4",
"day": "2",
"time": "13:00",
"main_location": "Trichy",
"sub_location": "Rockport",
"site_link": "www.rockport.com",
"description": "Test"
},
{
"sid": "24",
"tour_name": "4",
"day": "2",
"time": "12:00",
"main_location": "Madurai",
"sub_location": "Temple",
"site_link": "www.madurai.com",
"description": "Test "
},
{
"sid": "17",
"tour_name": "4",
"day": "1",
"time": "09:00",
"main_location": "Chennai",
"sub_location": "City Centre",
"site_link": "www.wikipedia.com",
"description": "test"
},
{
"sid": "16",
"tour_name": "4",
"day": "1",
"time": "08:00",
"main_location": "Chennai",
"sub_location": "Spencer Plaza",
"site_link": "www.spencer.com",
"description": "test"
},
{
"sid": "15",
"tour_name": "4",
"day": "1",
"time": "07:00",
"main_location": "Chennai",
"sub_location": "Express Avenue",
"site_link": "www.wikipedia.com",
"description": "test"
}]
From this json I want to create collapsible set like following type
day-->First collapsiple
---main_location-- >second collapsiple
---sublocation-->listview
Exmaple
day 1
--Chennai
---expressavenue
---Spencer Plaza
---City Centre
day 2
--Trichy
---Rockfort
-- Madurai
---Mahal
---Temple
I am trying following method but can't group like this
$(document).on('pageshow', '#itienary', function (event, ui) {
$.getJSON('url', function (data) {
var collapsible = [];
var days = [];
var collapsible1 = [];
var mainlocation = [];
$.each(data, function (i, v) {
collapsible.push(v.day);
$.each(collapsible, function (i, v) {
if ($.inArray(v, days) === -1) {
days.push(v);
days.sort();
}
});
});
$.each(days, function (j, main) {
var day = main;
var locations = '';
$.each(data, function (k, val) {
var mainloc = val.main_location;
if (val.day == day) {
collapsible1.push(mainloc);
}
$.each(collapsible1, function (i, v) {
if ($.inArray(v, mainlocation) === -1) {
mainlocation.push(v);
mainlocation.sort();
}
});
});
$.each(mainlocation, function (i, loc) {
var parent = loc;
var elements = '';
$.each(data, function (x, sub) {
var subLoc = sub.sub_location;
var time = sub.time;
var sitelink = sub.site_link;
if (sub.main_location == parent) {
elements += '<li><h2>' + subLoc + '</h2><p><strong>' + time + '</strong></p><p class="ui-li-aside"><strong>Sitelink: ' + sitelink + '</strong></p></a></li>';
}
});
$("#itinerary-list").append($("<div/>", {
"data-role": "collapsible",
"data-iconpos": "left",
"data-collapsed-icon": "arrow-d",
"data-expanded-icon": "arrow-u",
"class": day
}).append($("<h3/>").text("Day " + day)).appendTo($("<div/>"), {
"data-role": "collapsible",
"data-iconpos": "left",
"class": parent
}).append($("<h3/>").text(parent)).append($("<ul/>", {
"data-role": "listview",
"data-theme": "b"
}).append(elements).listview()));
$('#itinerary-list').collapsibleset('refresh');
});
});
});
});
How can I done this?