# Measuring Apdex from access logs in SumoLogic

Application Performance Index (Apdex) is a standardised method for calculating the perceived satisfaction of a user accessing your service. It divides all served requests into three categories: satisfied, tolerating, and frustrated.

A user's request is said to be satisfied when it occurs within some `T` value, such as 400ms, and is successful, e.g. 2xx or 3xx status codes.

A tolerating request is successful in more than `T`, and less than `4T`.

Frustrated requests exceed `4T` or fail, e.g. 4xx and 5xx status codes.

So how can we build this measure in SumoLogic? Let's take a look

```
| json auto field=raw_log
| if(statusCode matches "2*", if(responseTime <= {{Apdex_Time}}, 1, 0), 0) as satisfied_counter
| if(statusCode matches "2*", if(responseTime < {{Apdex_Time}} * 4 && responseTime > {{Apdex_Time}}, 1, 0), 0) as tolerating_counter
| timeslice 150 buckets
| count as total_logs, sum(satisfied_counter) as satisfied, sum(tolerating_counter) as tolerating by _timeslice
| ((satisfied+tolerating/2)/total_logs)as apdex
| fields apdex, _timeslice
```

We use structured logging, so our logs are JSON formatted, but you could do this just as easily via a regex capture on apache style access logs to extract the status code and response time.

This simply creates a counter for satisfied and tolerating using nested [if](https://help.sumologic.com/05Search/Search-Query-Language/Search-Operators/if-operator-and) functions with the [matches](https://help.sumologic.com/05Search/Search-Query-Language/Search-Operators/matches) operator. The frustrated queries are everything not captured by these two counters, so `count as total_logs` gives us everything else we need, assuming our log source only contains access logs.

And that's it! You can even overlay the percentage tolerating, frustrated, and satisfied if you like:

```
| ((satisfied+tolerating/2)/total_logs)as apdex
| satisfied/total_logs as satisfied_pct
| tolerating/total_logs as tolerating_pct
| (total_logs - satisfied - tolerating)/total_logs as frustrated_pct
| fields apdex, _timeslice, satisfied_pct, tolerating_pct, frustrated_pct
```
