DEV Community

David
David

Posted on • Edited on

Building a Personal Expense Tracker with OpenTelemetry and CI/CD

(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 with a single item

  • Transaction items have a description, an amount, a category for classification, and images

Transaction draft with item details

Other entities include Category, Account, Document, and Image.
The basic use cases include adding transactions and viewing statistics:

Add basic transaction
Statistics screen:

Statistics screen
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

Overview diagram

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)