Metricfire API

APIs and tradeoffs

 

Ways to get your data into Metricfire

Metricfire offers two ways to send your data:

The tradeoffs are that the HTTP API is quick to use, simple to implement, but not performant. The client libraries use UDP to send your data so they don't block your application. Sending thousands of datapoints per second should be no problem with the client libraries, but using the HTTP API will get you playing around faster.

For some quick testing and for applications where blocking is OK, use the HTTP API. For more serious deployments, use one of the client libraries. If you have any questions, send us email!

HTTP API

 

Basics

API URL

The base URL for all requests is: https://api.metricfire.com/v1/

Authentication

Authentication is simple - just send your API key as the username for HTTP Basic Authentication. Leave the password field empty, it will be ignored.

All requests must be made over SSL. Requests over plain HTTP will be rejected, and you will be warned about possibly having exposed your key.

API key format

API keys are 32 hex characters, split into the standard UUID group format of 8-4-4-4-12 characters.

An example API key is: 21510a33-aaec-491a-a353-d2aa0a657d08

You can find your API key in the Account Details page of your Metricfire account.

Successful API test

$ curl -D - https://your-api-key@api.metricfire.com/v1/test
HTTP/1.0 200 OK
Content-Type: text/plain

Test OK!

Failed API test

$ curl -D - https://invalid-api-key@api.metricfire.com/v1/test
HTTP/1.0 403 FORBIDDEN
Content-Type: text/plain

Invalid API Key

Sending metric data

To send datapoints, POST them to the metric path as a JSON structure.

Metric names

Metric and submetric strings should be basic ASCII alphanumeric characters. Space characters are acceptable, as are dashes, underscores, and some other simple symbols. For maximum compatibility with other tools, try to keep it simple.

Timestamps

You may optionally specify a UNIX timestamp for each value. The value will be recorded as having happened at that time. If no timestamp is provided, the value is assumed to have happened at the time the POST request was made.

Path format

/v1/metric/applicationname/metricname[.submetric[.submetric[...]]]

Where:

  • applicationname is the short, slugified form of the application name. This will appear in your list of applications in the graph building interface. For your reference this could be a filename, process name, or however you'd like to identify that application.
  • metricname is the name of the metric, usually basic ASCII alphanumeric characters.
  • submetric allows you to specify a tree of related, grouped metrics. These will all appear together in the graph building interface as a tree, rooted at metricname.

JSON datapoint structures

  • A bare integer or floating point value
    • Example: '7.2'
  • A list of integers or floating point values
    • Example: '[7.2,5.6,4]'
  • A list of lists, each containing a UNIX timestamp and an integer or floating point value
    • Example: '[[1332542763,7.2],[1332542766,5.6],[1332542767,4]]'

If you don't specify a UNIX timestamp, the time of the POST request will be assumed.

Sending a single datapoint to metric 'bar' under application 'foo'

$ curl -D - https://[apikey]@api.metricfire.com/v1/metric/foo/bar \
 --data-binary 1.6
HTTP/1.0 202 ACCEPTED

Sending multiple datapoints to metric 'bar' under application 'foo'

$ curl -D - https://[apikey]@api.metricfire.com/v1/metric/foo/bar \
 --data-binary [1.6,1.8,1.52]
HTTP/1.0 202 ACCEPTED

Querying metric data

Sending a GET request to a metric path will retrieve a series of datapoints.

URL Parameters

&start=

UNIX timestamp to begin the data series at, or a human readable time quantity. (default: none)

&end=

UNIX timestamp to end the data series at, or a human readable time quantity (default: none)

&timeperiod=

Number of seconds or a human readable time quantity (default: 24h)

&view=

The aggregation function to use on the data, like avg, min, max, sum, stdev, obvs (default: avg)

&datapoints=

Number of datapoints to aggregate to (default: 100)

Specifying start, end and timeperiod values is an error.

Returned JSON data structure

The response will be a list of datapoints. Each datapoint is a tuple containing a UNIX timestamp and a value.

[[1330909054, 0.22343], [1330909920, 0.22144], ... ]

Human readable time quantity

A 'human readable time quantity' is a short string like '1h', '2.5d', '1week', '2.5months', or just a number of seconds.

Aggregations / views

The full list of supported aggregations is:

  • avg
  • min
  • max
  • obvs (the number of times the metric was seen per second)
  • sum (the sum of all the values seen for that metric per second)
  • stdev (standard deviation)

Examples

/v1/metric/appname/foo.bar

The most recent 24 hours of data, average values, 100 datapoints

/v1/metric/appname/foo.bar?start=3d&timeperiod=1h

1 hour of data, starting three days ago, average values, 100 datapoints

/v1/metric/appname/foo.bar?start=1330145833&end=1330214600&datapoints=500&view=min

Approximately 19 hours of data between two specific UNIX timestamps, minimum values, 500 datapoints

Client libraries

 

Metricfire provides client libraries specifically made to guarantee fast, non-blocking operation.

The user should be free from the need to locally aggregate any data - just send it with the client and forget it.

Package Repos

The recommended way to get the client libraries is via our apt repository. Packages are signed, installation is fast, and upgrades are easy.

You can also just copy the client library files and place them next to your code. Direct URLs for the client libraries are provided in the relevant sections below.

apt package repository

# Tell apt where our package repository is. 
echo "deb http://public.apt.metricfire.com/ metricfire main" \
>> /etc/apt/sources.list
# Tell apt to import and trust our package signing key. 
apt-key adv --keyserver pgp.mit.edu --recv-keys 31CA6F02
# Update the package lists
apt-get update

# Install the relevant client library package
apt-get install python-metricfire
# or
apt-get install libmetricfire-php

rpm package repository

We intend to offer this, but we're not ready yet. For the moment, please fetch the client library files manually and place them near your code. If you want this feature soon, let us know!

For your convenience, direct links to the package library code are reproduced here:

Python client

Installation

The recommended way to get the client libraries is via our package repos - see the Package Repos section for details.

The Metricfire Python package name is python-metricfire

Alternatively, you may prefer to install the package manually, or just place the metricfire.py module near your code.

Usage

1. Import the metricfire module

import metricfire

2. Initialise the Metricfire client with your API key

metricfire.init("your-api-key")

3. Send metric keys and values

# A user logged in
metricfire.send("logins", 1)

# Oops, we caught an exception
metricfire.send("exceptions.ValueError", 1)

# Talking to a database took 34ms
metricfire.send("database.update", 0.034)

Metric naming

Metric names should be alphanumeric but self-descriptive. To group metrics into trees, use periods as separators, like cache.hits and cache.misses

Non-blocking operation

The metricfire.send(...) call is always non-blocking. The metricfire.init(...) call may block on DNS resolution if the adns python module is not installed on your system. On debian and ubuntu systems, this is available in the python-adns package.

Benchmark results

The metricfire.send(...) call is quite light. Some quick benchmark results:

100k iterations in 0.003448s, 0.034480us per iteration
100k iterations in 4.899722s, 48.997221us per iteration
100k calls in 0.010108s, 0.101080us per call
100k decorated calls in 5.416182s, 54.161820us per call

Using a Python decorator

# Use a decorator to record the execution time and requests/sec
# of a Django view
from django.http import HttpResponse
import metricfire
metricfire.init("your-api-key")

@metricfire.measure
def foo():
    return HttpResponse("bar", mimetype = "text/plain")

Sending simple data

# Generate some random numbers and send them to Metricfire
import random
import time

import metricfire
metricfire.init("your-api-key")

while True:
    metricfire.send("testdata.random", random.randrange(0, 100)
    time.sleep(0.5)

PHP client

Installation

The recommended way to get the client libraries is via our package repos - see the Package Repos section for details.

The Metricfire PHP package name is libmetricfire-php

Alternatively, you may prefer to install the package manually, or just place the metricfire.php file near your code.

Usage

1. Require the metricfire.php library

<?
require_once("metricfire.php");
?>

2. Initialise the Metricfire client with your API key

<?
metricfire_init("your-api-key");
?>

3. Send metric keys and values

<?
# A user logged in
metricfire_send("logins", 1)

# Talking to a database took 34ms
metricfire_send("database.update", 0.034);
?>

Non-blocking operation

While metricfire_send() is non-blocking, metricfire_init() may block for a moment while it waits for DNS responses. PHP doesn't offer any way to do non-blocking DNS requests, so we're looking into making or recommending an extension to allow this. In the meantime, a workaround is to provide the IP address of the UDP API endpoint to init(). Here's how you do it:

<?
// IP address of udp-api.metricfire.com 
metricfire_init("your-api-key", array("server" => "176.9.34.206"));
?>

If you do this, metricfire_init() will not block.

Sending simple data

<? 
// Send some random values to Metricfire
require_once("metricfire.php");

metricfire_init("your-api-key");
while(true)
{ 
    metricfire_send("testdata.random", rand(0, 100));
    usleep(500000);
}
?>

Node.js client

Installation

Install directly from npm:

$ npm install metricfire

Usage

1. Require the metricfire library

var metricfire = require("metricfire");

2. Initialise the Metricfire client with your API key

metricfire.init("your-api-key");

3. Send metric keys and values

// A user logged in
metricfire.send("logins", 1);

// Talking to a database took 34ms
metricfire.send("database.update", 0.034);

Sending simple data

// Send process memory usage to Metricfire every ten seconds.
var metricfire = require("metricfire");

metricfire.init("your-api-key");

setInterval(function(){
     memusage = process.memoryUsage();
     metricfire.send("memoryusage.rss", memusage.rss);
     metricfire.send("memoryusage.heaptotal", memusage.heapTotal);
     metricfire.send("memoryusage.heapused", memusage.heapUsed);
  }, 10000);

Java client

Installation

1. Download metricfire.jar

2. Download gson-2.1.jar if you don't already have it or a similar version of Google's gson library.

3. Download commons-logging.jar if you don't already use Apache Commons logging.

4. Make sure all three jars are available in your CLASSPATH:

   $ export CLASSPATH=$CLASSPATH:metricfire.jar:\ 
   gson-2.1.jar:commons-logging.jar:.

Usage

1. import com.metricfire.Metricfire

import com.metricfire.Metricfire;

2. Initialise the Metricfire client with your API key and the name of this application. Unlike the other client libraries, the Java one doesn't try to autodetect the name of the running application.

Metricfire.init("your-api-key", "appname");

3. Send metric keys and values

// A user logged in
Metricfire.getInstance().send("logins", 1);

// Talking to a database took 34ms
Metricfire.getInstance().send("database.update", 0.034);

Sending simple data

import com.metricfire.Metricfire;

public class Test {
    public static void main(String[] args) {
        Metricfire.init("your-api-key", "Test");
        Metricfire.getInstance().send("fooevent.bar", 1.4);

        doStuff();
    }

    static void doStuff() {
        Metricfire.getInstance().send("fooevent.baz", 650);

    }
}