(Originally posted on Medium)
I decided to make a personal app to track my expenses. Spreadsheets served me well, but there are some core features that I couldn’t get out of that
method:
- The ability to attach receipts to my records
- The ability to add images of the items I purchase
- Viewing and filtering the statistics across any time period without needing new PivotTables
There are excellent apps that already exist for this, including:
Though none of them fit exactly what I wanted. I could have kept searching, but beyond the need for a custom solution, I also saw the opportunity to challenge myself to learn certain topics, including:
- Unit Testing: with the Android and Spring frameworks
- Continuous Integration and Continuous Delivery: with Jenkins
- Observability: with OpenTelemetry and the Grafana stack
- Performance Testing: with JMeter
- Infrastructure: including Ansible, NGINX, and Linux concepts
And so I decided to go ahead and build the app for myself
App Structure
There are 2 versions of the app:
- Expense Tracker: offline, the first version of the app, and essentially my template for the next version. The source is available here.
- ExTrack: the full client-server version, split into the Java backend and the native Android version
Entities
- Transaction: made up of one or more items, bound to an account, and has a currency code
- Transaction items have a description, an amount, a category for classification, and images
Other entities include Category, Account, Document, and Image.
The basic use cases include adding transactions and viewing statistics:

This screen is loosely based on Simple Time Tracker's stats screen.
Architecture Overview
Most of this was done on my local network.
Tech Stack
- Backend: Java 17, Spring Boot, jOOQ, OpenAPI
- Observability: Grafana Loki 3.2, Grafana 11, Grafana Tempo 2.6, Prometheus 3.0, Grafana Pyroscope 1.18
- Infrastructure: Jenkins, NGINX 1.28, MySQL 8.0, various Prometheus exporters
- Operating Systems: Ubuntu 22, Windows 11, Windows 10
How it fits together
Prometheus reads metrics from a wide variety of exporters that I use. Promtail scrapes log files and sends them to Loki. Tempo is for distributed tracing. Using OpenTelemetry, all 3 signals are sent through NGINX to Alloy, and I visualize everything in Grafana. Pyroscope is a special case that I'll discuss in a separate article.
Conclusion
The next few articles will go into detail on how I learned each topic with the app, with the first 2 covering how I automated my testing and deployment processes.
Let me know your thoughts about this new series in the comments. I'll be cross-posting the remaining articles from Medium gradually.
Thank you for your time




Top comments (0)