how to create graph in grafana using Json data? - grafana

I have a sample json & I'm using JSON API plugin as i'm getting data from API
{
"data": [
{
"timeStamp": "2022-07-28 12:00:00",
"val": 10
},
{
"timeStamp": "2022-07-28 13:00:00",
"val": 11
},
{
"timeStamp": "2022-07-28 14:00:00",
"val": 20
},
{
"timeStamp": "2022-07-28 15:00:00",
"val": 30
},
{
"timeStamp": "2022-07-28 16:00:00",
"val": 35
},
{
"timeStamp": "2022-07-28 17:00:00",
"val": 39
}
]
}
I want to make graph using this data in grafana. Where X-axis should be time & y-axis should some number.
How can I plot graph from this data?

you can use Infinity plugin, to visualise your data as timeseries:
in my case I needed to add data transformation, to treat timeStamp as time:
I used API mocking service:
https://somegrafanademo.free.beeceptor.com/
to present data:

Related

Filtering objects by datetime field on MongoDB Atlas API returns ZERO (0) documents

We are trying out MongoDB atlas APIs for one of our projects. However, when we try to filter the data based on a datetime field, it returns zero documents.
API: https://data.mongodb-api.com/app/data-dfmng/endpoint/data/beta/action/find
METHOD: POST
PAYLOAD:
{
"collection": "trade",
"database": "sm",
"dataSource": "Cluster0",
"filter": {
"DATE1": "2022-06-02T00:00:00Z"
},
"sort": {
"SYMBOL": -1
},
"projection": {
"DATE1": 1,
"SYMBOL": 1,
"AVG_PRICE": 1
}
}
What could be wrong here?
Date should be in extended JSON format https://www.mongodb.com/docs/atlas/api/data-api/#date Unix timestamp in millis for 2022-06-02T00:00:00Z is 1654128000000 :
"filter": {
"DATE1": {"$date": {"$numberLong": "1654128000000"}}
},

GA4 (Google Analytics) sessions based on UTM params

I am trying to fetch sessions from GA4 which are relevant to specific UTM params.
In GA3 we were able to use segments (sessions::condition::ga:source==X;ga:medium==Y) but I can not find a way to do this on GA4.
POST https://analyticsdata.googleapis.com/v1beta/#{property}:runReport`
Payload like this:
body = {
"metrics": [
{
"name": "sessions::condition::ga:source==X;ga:medium==Y"
}
],
"dimensions": [
{
"name": "date"
}
],
"dateRanges": [
{
"startDate": '2022-01-01',
"endDate": '2022-01-30',
"name": "current_year"
}
]
}
Returns: Field sessions::condition::ga:source==X;ga:medium==Y is not a valid metric.. Is there a way to do this via new API?
Should I use dimension filter to achieve that? I need to query on both source&medium but it is not clear how do I do this?
"dimensionFilter": {
"filter": {
"fieldName": "firstUserMedium",
"stringFilter": {
"value": "Y"
}
}
}
A dimension filter on sessionSource & sessionMedium returns sessions that have those specific utm_source & utm_medium values. See the dimensions & metrics page for a description of these and other dimensions & metrics.
The needed dimension filter is similar to the following. See Dimension Filters in Creating a Report for more info.
"dimensionFilter": {
"andGroup": {
"expressions": [
{
"filter": {
"fieldName": "sessionSource",
"stringFilter": {
"value": "X"
}
}
},
{
"filter": {
"fieldName": "sessionMedium",
"stringFilter": {
"value": "Y"
}
}
}
]
}
},
Segments are not yet available today in the GA4 Data API.
I think you should check the dimensions and metrcis list for GA4 they dont start with ga
POST https://analyticsdata.googleapis.com/v1beta/properties/GA4_PROPERTY_ID:runReport
{
"dateRanges": [{ "startDate": "2020-09-01", "endDate": "2020-09-15" }],
"dimensions": [{ "name": "country" }],
"metrics": [{ "name": "activeUsers" }]
}
Also at this time i don't think it supports segments.

How to perform date arithmetic between nested and unnested dates in Elasticsearch?

Consider the following Elasticsearch (v5.4) object (an "award" doc type):
{
"name": "Gold 1000",
"date": "2017-06-01T16:43:00.000+00:00",
"recipient": {
"name": "James Conroy",
"date_of_birth": "1991-05-30"
}
}
The mapping type for both award.date and award.recipient.date_of_birth is "date".
I want to perform a range aggregation to get a list of the age ranges of the recipients of this award ("Under 18", "18-24", "24-30", "30+"), at the time of their award. I tried the following aggregation query:
{
"size": 0,
"query": {"match_all": {}},
"aggs": {
"recipients": {
"nested": {
"path": "recipient"
},
"aggs": {
"age_ranges": {
"range": {
"script": {
"inline": "doc['date'].date - doc['recipient.date_of_birth'].date"
},
"keyed": true,
"ranges": [{
"key": "Under 18",
"from": 0,
"to": 18
}, {
"key": "18-24",
"from": 18,
"to": 24
}, {
"key": "24-30",
"from": 24,
"to": 30
}, {
"key": "30+",
"from": 30,
"to": 100
}]
}
}
}
}
}
}
Problem 1
But I get the following error due to the comparison of dates in the script portion:
Cannot apply [-] operation to types [org.joda.time.DateTime] and [org.joda.time.MutableDateTime].
The DateTime object is the award.date field, and the MutableDateTime object is the award.recipient.date_of_birth field. I've tried doing something like doc['recipient.date_of_birth'].date.toDateTime() (which doesn't work despite the Joda docs claiming that MutableDateTime has this method inherited from a parent class). I've also tried doing something further like this:
"script": "ChronoUnit.YEARS.between(doc['date'].date, doc['recipient.date_of_birth'].date)"
Which sadly also doesn't work :(
Problem 2
I notice if I do this:
"aggs": {
"recipients": {
"nested": {
"path": "recipient"
},
"aggs": {
"award_years": {
"terms": {
"script": {
"inline": "doc['date'].date.year"
}
}
}
}
}
}
I get 1970 with a doc_count that happens to equal the total number of docs in ES. This leads me to believe that accessing a property outside of the nested object simply does not work and gives me back some default like the epoch datetime. And if I do the opposite (aggregating dates of birth without nesting), I get the exact same thing for all the dates of birth instead (1970, epoch datetime). So how can I compare those two dates?
I am racking my brain here, and I feel like there's some clever solution that is just beyond my current expertise with Elasticsearch. Help!
If you want to set up a quick environment for this to help me out, here is some curl goodness:
curl -XDELETE http://localhost:9200/joelinux
curl -XPUT http://localhost:9200/joelinux -d "{\"mappings\": {\"award\": {\"properties\": {\"name\": {\"type\": \"string\"}, \"date\": {\"type\": \"date\", \"format\": \"yyyy-MM-dd'T'HH:mm:ss.SSSSSSZ\"}, \"recipient\": {\"type\": \"nested\", \"properties\": {\"name\": {\"type\": \"string\"}, \"date_of_birth\": {\"type\": \"date\", \"format\": \"yyyy-MM-dd\"}}}}}}}"
curl -XPUT http://localhost:9200/joelinux/award/1 -d '{"name": "Gold 1000", "date": "2016-06-01T16:43:00.000000+00:00", "recipient": {"name": "James Conroy", "date_of_birth": "1991-05-30"}}'
curl -XPUT http://localhost:9200/joelinux/award/2 -d '{"name": "Gold 1000", "date": "2017-02-28T13:36:00.000000+00:00", "recipient": {"name": "Martin McNealy", "date_of_birth": "1983-01-20"}}'
That should give you a "joelinux" index with two "award" docs to test this out ("James Conroy" and "Martin McNealy"). Thanks in advance!
Unfortunately, you can't access nested and non-nested fields within the same context. As a workaround, you can change your mapping to automatically copy date from nested document to root context using copy_to option:
{
"mappings": {
"award": {
"properties": {
"name": {
"fields": {
"keyword": {
"ignore_above": 256,
"type": "keyword"
}
},
"type": "text"
},
"date": {
"type": "date"
},
"date_of_birth": {
"type": "date" // will be automatically filled when indexing documents
},
"recipient": {
"properties": {
"name": {
"fields": {
"keyword": {
"ignore_above": 256,
"type": "keyword"
}
},
"type": "text"
},
"date_of_birth": {
"type": "date",
"copy_to": "date_of_birth" // copy value to root document
}
},
"type": "nested"
}
}
}
}
}
After that you can access date of birth using path date, though the calculations to get number of years between dates are slightly tricky:
Period.between(LocalDate.ofEpochDay(doc['date_of_birth'].date.getMillis() / 86400000L), LocalDate.ofEpochDay(doc['date'].date.getMillis() / 86400000L)).getYears()
Here I convert original JodaTime date objects to system.time.LocalDate objects:
Get number of milliseconds from 1970-01-01
Convert to number of days from 1970-01-01 by dividing it to 86400000L (number of ms in one day)
Convert to LocalDate object
Create date-based Period object from two dates
Get number of years between two dates.
So, the final aggregation query looks like this:
{
"size": 0,
"query": {
"match_all": {}
},
"aggs": {
"age_ranges": {
"range": {
"script": {
"inline": "Period.between(LocalDate.ofEpochDay(doc['date_of_birth'].date.getMillis() / 86400000L), LocalDate.ofEpochDay(doc['date'].date.getMillis() / 86400000L)).getYears()"
},
"keyed": true,
"ranges": [
{
"key": "Under 18",
"from": 0,
"to": 18
},
{
"key": "18-24",
"from": 18,
"to": 24
},
{
"key": "24-30",
"from": 24,
"to": 30
},
{
"key": "30+",
"from": 30,
"to": 100
}
]
}
}
}
}

Subtract two values in Kibana for specific timestamps

This is the first time Im doing this and cant seem to find an online resource.
The index is aggregated at a daily level. So one record per day.
26 April:
{
"_index": "gamers",
"_type": "dailyAgg",
"_id": "dailyAgg-2015-04-26T00:00:00Z",
"_score": null,
"_source": {
"timestamp": "2017-04-26T00:00:00Z",
"player_count": 800
},
"timestamp": [
1493164800000
]
},
"sort": [
1493164800000
]
}
25 April:
{
"_index": "gamers",
"_type": "dailyAgg",
"_id": "dailyAgg-2017-04-25T00:00:00Z",
"_score": null,
"_source": {
"timestamp": "2017-04-25T00:00:00Z",
"player_count": 500
},
"timestamp": [
1493078400000
]
},
"sort": [
1493078400000
]
}
What I need is:
player_count(Today) - player_count(Yesterday)
=> player_count(26 April) - player_count(25 April) = 800 - 500 = 300
I've tried scripted field and painless scripts, but cant pull the data for the given date.
This is the solution I ended up using: Custom Plugin

Flask restful parser list dictionary

I have an example parse request list dictionary:
{
"shopping_cart": [{
"id": 23323,
"qty": 10
}, {
"id": 34232,
"qty": 9
}, {
"id": 34232,
"qty": 9
}]
}
How can i parse it use flask_restful RequestParser ?
Use something like this :)
self.postreqparse = reqparse.RequestParser()
self.postreqparse.add_argument("shopping_cart", type=dict, action="append")