Time Chart

The time chart widget, the most commonly used widget in Humio, displays bucketed time series data on a time line.

Usage

The time chart widget expects a very specific input format that is produced by its companion query function timechart . We recommend you read the function documentation for timechart .

Example 1: Metric Data

Say you have a service that periodically writes metrics to its logs. This could be tools such as DropWizard or Micrometer or a system monitoring tool like MetricBeat.

In this case we will have JSON logs that could look something like this:

{ "type": "metrics", "id": "1", "ts": "2018-11-01T00:10:11.001", "disk0": 11.21, "disk1": 21.14, "disk2": 12.01  }
{ "type": "metrics", "id": "2", "ts": "2018-11-01T00:10:13.106", "disk0": 11.21, "disk1": 21.14, "disk2": 12.01  }
{ "type": "metrics", "id": "3", "ts": "2018-11-01T00:10:18.771", "disk0": 10.57, "disk1": 20.41, "disk2": 11.91  }
{ "type": "metrics", "id": "4", "ts": "2018-11-01T00:10:18.772", "disk0": 9.15, "disk1": 19.12, "disk2": 10.07  }

where disk0-2 represent some metrics that you would like to create a time chart for.

type = metrics | timechart(function=[max(disk0, as="Disk 0"), max(disk1, as="Disk 1"), max(disk2, as="Disk 2")])

Notice that we provide several aggregate functions to the function parameter. This is because we want to work on several fields on each input event. In this example it creates three series in the resulting time chart — one for each metric. We used the max function on each field. This means that when the timechart function buckets the data it uses the larger number within the bucket to represent the value of the series in the bucket. In other words, imagine that event id=3 and id=4 in JSON events above end up in the same bucket (Which is not an unreasonable assumption since their timestamps are only 1 ms apart!).

If we use max we will get the largest value of the field, e.g. max(disk0) of id=3 and id=4 would be 10.57 even though id=4 occurs later in the stream. Alternatively we could have used avg which would have given the average of the two values of disk0, in this case 9.86. Which aggregate function to use depends on what you what to visualize.

Example 2: Log Levels

If you have logs that contain log levels like INFO, ERROR, and WARN, it can be interesting to visualize them over time. Say you have logs like:

2018-10-10T01:10:11.322Z [INFO] User Logged in. userId=10, ...
2018-10-10T01:10:12.172Z [WARN] Invalid Login Attempt. userId=10, ...
2018-10-10T01:10:14.122Z [INFO] Database Query. timeMs=20 connection=12.10...
2018-10-10T01:10:15.312Z [INFO] Database Query. timeMs=10 connection=12.10...
2018-10-10T01:10:16.912Z [INFO] Database Query. timeMs=21 connection=12.10...

and you have a parser that extracts a field called loglevel from each line. You can do something like:

timechart(loglevel)

This will count the number of occurrences of events that have a field called loglevel and put them in a series in the time chart based on their value. Based on the example data above this would create a time chart with two series, INFO and WARN.

By default the count function is used to calculate the value of each bucket, but you can easily plot other values by specifying other functions in the function property of the timechart function. For instance if we use the avg function on the field timeMs:

timechart(loglevel, function=avg(timeMs))

We can see the average time in milliseconds that a database query takes. The percentiles function is very useful as an aggregate function in time charts when you wish to visualize response times like this.