Baike.dev
All toolsOnline toolsAI codingTrendingOpen sourceNewsSubmit
Log in
< Back to tools
R

recorder

> 编程语言
Open source

Store and access data published by OwnTracks apps

1.2K stars0 likes0 views
WebsiteGitHub

About

Store and access data published by OwnTracks apps

OwnTracks Recorder

The OwnTracks Recorder is a lightweight program for storing and accessing location data published via MQTT (or HTTP) by the OwnTracks apps. It is a compiled program which is easy to install and operate even on low-end hardware, and it doesn't require an external database.

There are two main components: the Recorder obtains data via MQTT subscribes or HTTP POST, stores the data in plain files and serve it via its built-in REST API, and the ocat command-line utility reads stored data in a variety of formats.

We developed the Recorder as a one-stop solution to storing location data published by our OwnTracks apps (iOS and Android) and retrieving this data. Our previous offerings (m2s, o2s/Pista) also work of course, but we believe the Recorder is best suited to most environments.

See also HOOKS.md, DESIGN.md, and STORE.md for more information on Lua hooks, program design, and storage layout, respectively.

Table of Contents

  • recorder
  • Installing
    • Packages
      • systemd service
    • Docker
    • Building from source
      • Prerequisites
      • Building
  • Getting started
  • ot-recorder options
  • Configuration file
  • Reverse proxy
    • nginx
    • Apache
  • The HTTP Server
    • Example functionality
      • Last position of a particular user
      • Display map with points starting at a particular date
      • Display a track (a.k.a. linestring)
      • Tabular display
      • Live map
  • ocat
    • Environment
    • Examples
      • List users and devices
      • Show the last position reported by a user
      • What were the last 4 positions reported?
  • Reverse Geo
    • Precision
    • The geo cache
  • Monitoring
  • Lua hooks
  • Views
    • view JSON
    • Authentication
  • HTTP mode
    • Friends in HTTP mode
  • Advanced topics
    • Browser API keys
    • The LMDB database
      • topic2tid
      • keys
      • friends
  • Encryption
  • Tips and Tricks
    • Gatewaying HTTP to MQTT
    • Override reverse-geo precision

recorder

The Recorder serves two purposes:

  1. It subscribes to an MQTT broker and reads messages published from the OwnTracks apps, storing these in a particular fashion into what we call the store which is basically a bunch of plain files on the file system. Alternatively the Recorder can listen on HTTP for OwnTracks-type JSON messages POSTed to its HTTP server.
  2. It provides a Web server which serves static pages, a REST API you use to request data from the store, and a WebSocket server. The distribution comes with a few examples of how to access the data through its HTTP interface (REST API). In particular a table of last locations has been made available as well as a live map which updates via the Recorder's WebSocket interface when location publishes are received. In addition we provide maps with last points or tracks using the GeoJSON produced by the Recorder.

Installing

We provide ready-to-run packages for a limited number of platforms on our package repository, and we provide a Docker image of the Recorder directly from the Docker hub.

If those don't work for you, you can build from source.

Packages

We create packages for releases for a few distributions. Please note:

  • that these packages might depend on libmosquitto1 from the Mosquitto project.
  • we typically do not build packages for distributions which have been superceded upstream

Binaries (ocat, ot-recorder) from these packages run setuid to user owntracks so that they work for all users of the system. Note that, say, certificate files you provide must therefore also be readable by the user owntracks.

Debian 10 "Buster":

  • we no longer build for this distribution, but you should be able to compile from source.

Debian 11 "Bullseye":

  • we no longer build for this distribution, but you should be able to compile from source.

Debian 12 "Bookworm":

  • we no longer build for this distribution, but you should be able to compile from source or use older versions from the package repository.

Debian 13 "Trixie":

  • install with:
…

--geokey "opencage:xxxxxxxxxxxxxxxxxxxxxx" # for OpenCage --geokey "xxxxxxxxxxxxxxxxxxxxxx" # for Google --geokey "revgeod:localhost:8865" # for Revgeod (host:port)

…

OTR_STORAGEDIR="/var/spool/owntracks/recorder/store"

…

server { listen 8080; server_name 192.168.1.130;

location / {
    root   html;
    index  index.html index.htm;
}

# Proxy and upgrade WebSocket connection
location /owntracks/ws {
    rewrite ^/owntracks/(.*)    /$1 break;
    proxy_pass      http://127.0.0.1:8083;
    proxy_http_version  1.1;
    proxy_set_header    Upgrade $http_upgrade;
    proxy_set_header    Connection "upgrade";
    proxy_set_header    Host $host;
    proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
}

location /owntracks/ {
    proxy_pass      http://127.0.0.1:8083/;
    proxy_http_version  1.1;
    proxy_set_header    Host $host;
    proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header    X-Real-IP $remote_addr;
}

# OwnTracks Recorder Views (requires /view, /static, /utils)
location /owntracks/view/ {
     proxy_buffering         off;            # Chrome
     proxy_pass              http://127.0.0.1:8083/view/;
     proxy_http_version      1.1;
     proxy_set_header        Host $host;
     proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
     proxy_set_header        X-Real-IP $remote_addr;
}
location /owntracks/static/ {
     proxy_pass              http://127.0.0.1:8083/static/;
     proxy_http_version      1.1;
     proxy_set_header        Host $host;
     proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
     proxy_set_header        X-Real-IP $remote_addr;
}
location /owntracks/utils/ {
     proxy_pass              http://127.0.0.1:8083/utils/;
     proxy_http_version      1.1;
     proxy_set_header        Host $host;
     proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
     proxy_set_header        X-Real-IP $remote_addr;
}

# HTTP Mode
location /owntracks/pub {
    auth_basic              "OwnTracks pub";
    auth_basic_user_file    /usr/local/etc/nginx/owntracks.htpasswd;
    proxy_pass              http://127.0.0.1:8083/pub;
    proxy_http_version      1.1;
    proxy_set_header        Host $host;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header        X-Real-IP $remote_addr;

    # Optionally force Recorder to use username from Basic
    # authentication user. Whether or not client sets
    # X-Limit-U and/or uses ?u= parameter, the user will
    # be set to $remote_user.
    proxy_set_header        X-Limit-U $remote_user;
}

}


### Apache

This will hand URIs which begin with `/owntracks/` to the Recorder.

WebSocket URL endpoint

a2enmod proxy_wstunnel

ProxyPass /owntracks/ws ws://127.0.0.1:8083/ws keepalive=on retry=60 ProxyPassReverse /owntracks/ws ws://127.0.0.1:8083/ws keepalive=on

Static files

ProxyPass /owntracks http://127.0.0.1:8083/ ProxyPassReverse /owntracks http://127.0.0.1:8083/

TODO: add views


### [Caddy](https://caddyserver.com)

recorder.example.org { encode gzip reverse_proxy http://localhost:8083 basicauth * { # create new password hashes with caddy hash-password --plaintext yourpasswordhere john_doe JDJhJDE0JDBNc0FyNGd3b3JzejBTaExUZnkxdnV2THZSUUdHNzJYZmdVTzN3NlZXcjh2YXJLQi5KY04u } }

…

$ curl http://127.0.0.2:8083/api/0/last -d user=demo -d device=iphone [ { "tst": 1440405601, "acc": 10, "_type": "location", "alt": 262, "lon": 13.60279820860699, "vac": 6, "vel": 18, "lat": 51.06263391678321, "cog": 82, "tid": "NE", "batt": 99, "username": "demo", "device": "iphone", "topic": "owntracks/demo/iphone", "ghash": "u31dmx9", "isotst": "2015-08-24T08:40:01Z", "disptst": "2015-08-24 08:40:01", "cc": "DE", "addr": "E40, 01156 Dresden, Germany" } ]


#### Display map with points starting at a particular date

By specifying a `format` we can produce GeoJSON, say. Normally, the API retrieves the last 6 hours of data but we can extend or limit this with the `from` and `to` parameters.

http://127.0.0.2:8083/map/index.html?user=demo&device=iphone&format=geojson&from=2014-01-01

…

xml

1440405601 10.000000 262 13.602798 6.000000 18 51.062634 82 NE 99 demo iphone owntracks/demo/iphone u31dmx9 2015-08-24T08:40:01Z 2015-08-24 08:40:01 DE E40, 01156 Dresden, Germany

…

%Y-%m-%dT%H:%M:%S %Y-%m-%dT%H:%M %Y-%m-%dT%H %Y-%m-%d %Y-%m

…

$ ocat --list { "results": [ "demo" ] }


From which devices has user `demo` published data?

$ ocat --list --user demo { "results": [ "iphone" ] }


#### Show the last position reported by a user

Where was `demo`'s iPhone last seen? (Omit `--user` and `--device` to get LAST for all users and devices.)

$ ocat --last --user demo --device iphone [ { "tst": 1440405601, "acc": 10, "_type": "location", "alt": 262, "lon": 13.60279820860699, "vac": 6, "vel": 18, "lat": 51.06263391678321, "cog": 82, "tid": "NE", "batt": 99, "username": "demo", "device": "iphone", "topic": "owntracks/demo/iphone", "ghash": "u31dmx9", "isotst": "2015-08-24T08:40:01Z", "disptst": "2015-08-24 08:40:01", "cc": "DE", "addr": "E40, 01156 Dresden, Germany" } ]

…

$ ocat --user demo --device iphone --limit 4 --format csv --fields isotst,vel,addr isotst,vel,addr 2015-08-24T08:40:01Z,18,"E40, 01156 Dresden, Germany" 2015-08-24T08:35:01Z,40,"E40, 01723 Wilsdruff, Germany" 2015-08-24T08:30:00Z,50,"A14, 01683 Nossen, Germany" 2015-08-24T08:24:59Z,40,"A14, 04741 Roßwein, Germany"


## Reverse Geo

If not disabled with option `--norevgeo`, the Recorder will attempt to perform a reverse-geo lookup on the location coordinates it obtains. These can be either

1. obtained via a Lua function you define (see [doc/HOOKS.md](doc/HOOKS.md))
2. obtained via a call to one of the supported reverse geocoders (see `--geokey`)

Results of lookups are stored in an LMDB database. If a lookup is not possible, for example because you're over quota, the service isn't available, etc., Recorder keeps tracks of the coordinates which could *not* be resolved in a file named `missing`:

$ cat store/ghash/missing u0tfsr3 48.292223 8.274535 u0m97hc 46.6527

Issues· 0 open

View all issuesOpen on GitHub

No open issues yet, or sync has not completed.

> Tags

Cgeolocationhttpjpdupjson

No comments yet. Be the first to share.

> Details

PublishedAug 1, 2026
UpdatedSep 17, 2026
Category编程语言
PricingOpen source

> Related tools

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言