Send metric to Application Insights

I already posted how to send telemetry to Application Insights REST endpoint using PowerShell one-liner. This post shows how to send metric using curl.

Here is a minimal JSON represents the metric. Set iKey where to send the metric, time this metric reported for and metrics collection. Note, that baseType should be set to MetricData. The field name in envelope is redundant in the context of this API.

Here is an example of JSON:

{
    "iKey": "f4731d25-188b-4ec1-ac44-9fcf35c05812",
    "time": "2017-10-27T00:01:52.9586379Z",
    "name": "MetricData", 
    "data": {
        "baseType": "MetricData",
        "baseData": {
            "metrics": [ 
                {
                    "name": "Custom metric",
                    "value": 1,
                    "count": 1
                }
            ]
        }
    }
}

Microsoft bond definition for the MetricData document is located in ApplicationInsights-Home repository.

Now you can send this JSON to Application Insights endpoint:

curl -d '{"name": "MetricData", "time":"2017-10-27T00:01:52.9586379Z",
    "iKey":"f4731d25-188b-4ec1-ac44-9fcf35c05812",
    "data":{"baseType":"MetricData","baseData":
    {"metrics":[{"name":"Custom metric","value":1,"count":1}]}}}' 
    https://dc.services.visualstudio.com/v2/track

StdOut:
{"itemsReceived":1,"itemsAccepted":1,"errors":[]}

You can send multiple new-line delimited metrics in one http POST.

curl -d $'{"name": "MetricData", "time":"2017-10-27T00:01:52.9586379Z",
    "iKey":"f4731d25-188b-4ec1-ac44-9fcf35c05812",
    "data":{"baseType":"MetricData","baseData":
    {"metrics":[{"name":"Custom metric on line 1","value":1,"count":1}]}}}\n

    {"name": "MetricData", "time":"2017-10-27T00:01:52.9586379Z",
    "iKey":"f4731d25-188b-4ec1-ac44-9fcf35c05812",
    "data":{"baseType":"MetricData","baseData":
    {"metrics":[{"name":"Custom metric on line 2","value":1,"count":1}]}}}' 
    https://dc.services.visualstudio.com/v2/track

StdOut:
{"itemsReceived":2,"itemsAccepted":2,"errors":[]}

If you want to add a few dimensions to your metric - you can use properties collection.

{
    "iKey": "f4731d25-188b-4ec1-ac44-9fcf35c05812",
    "time": "2017-10-27T00:01:52.9586379Z",
    "name": "MetricData", 
    "data": {
        "baseType": "MetricData",
        "baseData": {
            "metrics": [ 
                {
                    "name": "Custom metric",
                    "value": 1,
                    "count": 1
                }
            ],
            "properties": {
                "dimension1": "value1",
                "dimension2": "value2"
            }
        }
    }
}

Now you can create stacked area chart using analytics query:

customMetrics 
    | summarize avg(value) by tostring(customDimensions.dimension1), bin(timestamp, 1m) 
    | render areachart kind=stacked 

There are no limits on number of dimensions or its cardinality. You can even summarize by derived field. For example, you can aggregate a metric by substring of a dimension value.

customMetrics 
    | extend firstChar = substring(tostring(customDimensions.dimension1), 0, 2)
    | summarize avg(value) by firstChar, bin(timestamp, 1m) 
    | render areachart kind=stacked 

You can also specify standard dimensions using tags. This way you associate your metric with the specific application role or role instance. Or mark it with the user and account. Using standard dimensions enable better integration with the rest of telemetry. This example lists a few standard dimensions you can specify:

{
    "iKey": "f4731d25-188b-4ec1-ac44-9fcf35c05812",
    "time": "2017-10-27T00:01:52.9586379Z",
    "name": "MetricData", 
    "tags": {
        "ai.application.ver": "v1.2",
        "ai.operation.name": "CheckOut",
        "ai.operation.syntheticSource": "TestInProduction: Validate CheckOut",
        "ai.user.accountId": "Example.com",
        "ai.user.authUserId": "sergey@example.com",
        "ai.user.id": "qwoijcas",
        "ai.cloud.role": "Cart",
        "ai.cloud.roleInstance": "instance_0"
    },
    "data": {
        "baseType": "MetricData",
        "baseData": {
            "metrics": [ 
                {
                    "name": "Custom metric",
                    "value": 1,
                    "count": 1
                }
            ]
        }
    }
}

You can also set more aggregates for the metric. Besides value (which is treated as sum) and count you can specify min, max, and standard deviation stdDev

{
    "iKey": "f4731d25-188b-4ec1-ac44-9fcf35c05812",
    "time": "2017-10-27T00:01:52.9586379Z",
    "name": "MetricData", 
    "data": {
        "baseType": "MetricData",
        "baseData": {
            "metrics": [ 
                {
                    "name": "Custom metric",
                    "value": 5,
                    "min": 0,
                    "max": 3,
                    "stdDev": 1.52753,
                    "count": 3
                }
            ]
        }
    }
}

##Price of a single metric

Application Insights charges $2.3 per Gb of telemetry. Let’s say the metric document you send is 500 bytes. Metric with just name and value have size of 200 bytes. So 500 bytes includes few dimensions. If you send one metric per minute, you are paying for 24 * 60 * 500 * 30 bytes per month or 0.02 Gb per month. If you send this metric from 5 different instances of your application - it is 0.1 Gb or 23 cents. I’m not taking into account the first free Gb you are getting every month.

With Application Insights today, you cannot pay flat rate for a metric. On other hand, you get rich analytics language on every metric document you sent, not just access to metric aggregates.

##Metrics REST API shortcomings

Multiple metrics in a single document

Metrics document schema defines an array of metrics. However Application Insights only supports one element in this array.

When this limitation is removed - every metric in collection supports its own set of dimensions. Today, dimensions are set on document level to align with all other telemetry types that Application Insights support.

Aggregation Interval

Application Insights assumes 1-minute aggregation for all reported metrics. You can easily work around this assumption using Analytics queries.

In standard metrics aggregator custom property MS.AggregationIntervalMs used to indicate the aggregation interval. This property used primarily to smooth out metrics after Flush was called before the aggregation period ended.

##APIs of other metrics solutions:

AWS CloudWatch

SignalFX

Google StackDriver

Comments

comments powered by Disqus