ZerØ Analytics is a Google Analytics alternative with:
- Zero personal data usage
- Zero vendor lock-in
- Zero complexity
- And a googol of love!
- Single native executable
- Shameful copy of the Google Analytics tag
- Multiple output support (Loki, Elasticsearch, Prometheus, files, ... )
- JSON or templatized output
- Track visited pages, uncaught errors and custom events
- Optional Time on Page support thanks to Beacon API
- Optional GeoIP support thanks to DB-IP
- Customizable beacon image (1px or badge)
- Usage control limitation
Here an example of what you can get using Grafana with Loki:
By compiling from sources:
$ go get -v github.com/ncarlier/za
Or by downloading the binary regarding your architecture:
$ curl -sf https://gobinaries.com/ncarlier/za | sh
Or by using Docker:
$ docker run -d --name=zero-analytics ncarlier/za
Start the server:
# init and customize the configuration file
za init-config -f config.toml
# start server
za -c config.toml serve
The configuration is a TOML file structured like this:
# ZerØ Analytics configuration file
[log]
## Log level
level = "info"
## Log format
format = "text"
[http]
## HTTP listen address
listen_addr = ":8080"
[geo-ip]
## Geo IP database
database = "./var/dbip-country-lite.mmdb"
[global]
[global.tags]
dc = "eu-west-1"
user = "$USER"
# List of trackers
[[trackers]]
## Tracking ID
tracking_id = "UA-XXXX-Y"
## Only HTTP request from this origin will be collected
origin = "http://localhost:8000"
## Badge configuration (<title>|<label>|<color>)
badge = "zero|analytics|#00a5da"
# Outputs configuration
[[outputs.file]]
## Files to write to, "stdout" is a specially handled file.
files = ["stdout"]
## Data format to output
data_format = "json"
## Condition to use this output
## See syntax here: https://expr-lang.org/docs/language-definition
condition == 'tid == "UA-XXX-Y"'
A complete and documented example can be generated with za init-config
command.
ZerØ Analytics is able to format and write collected events to multiple outputs:
This output is usefull if you want to process events by an external toolchain.
[[outputs.file]]
## Files to write to, "stdout" is a specially handled file.
files = ["/tmp/events.log"]
Note: stdout
is a special keyword used to write events to the process standard output (stdout).
This output is usefull if you want to process events by an external service.
[[outputs.http]]
## URL is the address to send events to
url = "http://localhost:8081"
## Timeout for HTTP message
timeout = "2s"
## HTTP method, one of: "POST" or "PUT"
method = "POST"
## HTTP Basic Auth credentials
# username = "username"
# password = "pa$$word"
## Compress body request using GZIP
gzip = true
Loki is a horizontally-scalable, highly-available, multi-tenant log aggregation system inspired by Prometheus.
[[outputs.loki]]
## Loki URL
url = "http://localhost:3100"
## Timeout
timeout = "2s"
## Batch size
batch_size = 10
## Batch interval
batch_interval = "10s"
Prometheus collects and stores its metrics as time series data, i.e. metrics information is stored with the timestamp at which it was recorded, alongside optional key-value pairs called labels.
[[outputs.prom]]
## Address to listen on
listen = ":9213"
## Path to publish the metrics on.
path = "/metrics"
## Metric prefix name
prefix = "za_"
[[outputs.prom.metrics]]
## Metric name
name = "pageview_total"
## Filter on specific event type
## Values: "pageview", "exception" ("event" otherwise)
type = "pageview"
## Metric labels can be specified here in key="value" format where value is the event property name (see below).
[outputs.prom.metrics.labels]
tid = "tid"
page = "path"
An output can be used depending on the result of a conditional expression. The expression used the Expr Lang syntax.
Example:
[[outputs.file]]
## Write events to STDOUT
files = ["stdout"]
## Writes events only coming from Firefox
condition = 'browser == "Firefox"'
See below for available event properties.
Some outputs are able to send formated events.
This is the case for Loki
, HTTP
, and File
.
By default they format the event data as JSON
:
{
"tid": "UA-XXXX-Y",
"browser":"Chrome",
"os":"Linux x86_64",
"tags": {"dc":"eu-west-1","user":"nicolas"},
"timestamp": "2020-09-27T22:01:58.623366267Z",
"language": "en-US",
"hostname": "http://localhost",
"path": "/classic.html",
"referer": ""
}
You can also format data as a string by using Go Template. By default the template is the Common Log Format.
Add this to your output configuration in order to specify data format:
## Data format to output ("json" or "template")
data_format = "template"
## Go template used by the template data format. By defaut "Common Log Format".
data_format_template = "{{.client_ip}} {{.hostname}} - [{{.timestamp}}] \"GET {{.path}} {{.protocol}}\" 200 1 \"{{.referer}}\" \"{{.user_agent}}\""
See below for available event properties.
The following event properties are available:
Property name | Decsription | pageview | exception | event |
---|---|---|---|---|
tid | Event ID | ✓ | ✓ | ✓ |
client_ip | Client IP | ✓ | ✓ | ✓ |
user_agent | User Agent | ✓ | ✓ | ✓ |
country | Decoded country (if found) | ✓ | ✓ | ✓ |
os | Decoded operating system | ✓ | ✓ | ✓ |
browser | Decoded browser | ✓ | ✓ | ✓ |
tags | Tags | ✓ | ✓ | ✓ |
timestamp | Tags | ✓ | ✓ | ✓ |
protocol | HTTP verv | ✓ | - | - |
language | Browser language | ✓ | - | - |
hostname | URL hostname | ✓ | - | - |
path | URL path | ✓ | - | - |
referer | HTTP Referer | ✓ | - | - |
new_visitor | Is new visitor | ✓ | - | - |
new_session | Is new session | ✓ | - | - |
top | Time on page | ✓ | - | - |
msg | Error message | - | ✓ | - |
line | Error line | - | ✓ | - |
column | Error column | - | ✓ | - |
url | Error URL | - | ✓ | - |
error | Error | - | ✓ | - |
payload | Event custom payload | - | - | ✓ |
To start tracking pageviews, copy the following tracking snippet to all pages of the website you want to track.
<!-- Zero Analytics script -->
<script>
(function(i, s, o, g, r, a, m){
s[r]=s[r]||function(){
(s[r].q=s[r].q||[]).push(arguments)
};
a=i.createElement(o),
m=i.getElementsByTagName(o)[0];
a.async=1; a.src=g; a.id='za-script';
m.parentNode.insertBefore(a,m)
})(document, window, 'script', 'http://localhost:8080/za.js', 'za');
za('create', 'UA-XXXX-Y', 'auto');
za('send', 'pageview');
</script>
<!-- End Zero Analytics script -->
While the snippet described before ensures the script will be loaded and executed asynchronously on all browsers, it has the disadvantage of not allowing modern browsers to preload the script.
This alternative async snippet adds support for preloading:
<!-- Zero Analytics script -->
<script>
window.za = window.za||function(){(za.q=za.q||[]).push(arguments)};za.l=+new Date;
za('create', 'UA-XXXX-Y', 'auto');
za('send', 'pageview');
</script>
<script async src='http://localhost:8080/za.js' id="za-script"></script>
<!-- End Zero Analytics script -->
The analytics script is able to track 3 kinds of events: page views, errors and custom events:
<!-- Zero Analytics script -->
<script>
...
za('send', 'pageview'/*, {top: true}*/);
</script>
<!-- End Zero Analytics script -->
As soon the page is loaded, the analytics script will send page hit to the collector endpoint.
Alternatively you can measure the time spent on a page (Time on Page) by activating the option Time on Page
({top: true}
).
This will use the Beacon API of the browser instead of the usual tracking method.
<!-- Zero Analytics script -->
<script>
...
za('send', 'error');
</script>
<!-- End Zero Analytics script -->
As soon a uncaught error is thrown, the analytics script will catch and send the error to the collector endpoint.
// Somewhere in your site
za('send', 'event', {"foo": "bar"});
The analytics script will send the event payload to the collector endpoint.
ZerØ Analytics is able to create tracked badges, which can easily be included in GitHub readmes or any other web page.
You can customize the badge using the tracker section configuration.
Then you can insert the badge into your web page:
<!-- Somewere in your site -->
<img src="http://localhost:8080/badge/UA-XXXX-Y.svg" />
Note that a badge hit will produce a custom event. This means that you are able to send a JSON base64 encode payload by using query parameters:
<!-- Somewere in your site -->
<img src="http://localhost:8080/badge/UA-XXXX-Y.svg?d=eyJmb28iOiJiYXIifQ%3D%3D" />
ZerØ Analytics is provided under the GNU Affero General Public License Version 3 (AGPLv3).
ZerØ Analytics is a Google Analytics alternative focused on privacy and simplicity.
Copyright (C) 2020 Nicolas Carlier
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>