homepage / weblog / micro / videos / theme / XXIIVV

Posted on 2025-05-24 / Tags: ,

Disclaimer: It's not a documentation of any kind, I have no idea how to write documentation correctly. It's just a bunch of chaotic notes on how and why I created this logging system, how I use it, and what statistics I'm interested in gathering from all the collected data.

Intro

As I promised earlier, here's a quick explanation of my new logging system. Technically it's the 3rd iteration - the first one was a bash script that added entries into a bunch of JSON files with a different number of arguments, and it worked pretty badly - there was a lack of ways to turn it into somewhat useful statistics. After that, I made an attempt to create a TUI version of it using Python, Rich, Textual, and SQLite - I failed miserably and spent 3 days in frustration.

It was obviously too complicated for me, since I don't have any real tech background. So, for the final (hopefully) 3rd version, I decided to make it a pure CLI - it's much easier for me to maintain and fix than a TUI, and it's much more portable because it has fewer dependencies. For this version, I used Python, SQLite, and Tabulate.

Overview

While researching other solutions, I found a bunch of amazing trackers that inspired me to continue. Here's the main ones I used as references while creating my own tracker:

And here's a collection of similar tools that I found later:

As you can see, all these tools have a big difference from my initial idea - start and end timecodes for each activity. Here I want to address the first problem: I will never track exact timestamps of when I start or end doing something. Moreover, I want to have the ability to add entries retrospectively, after some time. So, I found a compromise that worked for me - instead of time frames, I added a duration property.

Of course, I want to make the system as flexible as possible, but realistically, I need to make it as easy to use as possible. Because if it's gonna be too complicated, I'll give up on it after a week. But I really want to have all this useful statistics. During the day, I write down all the things I do in my small notebook anyway, so it's easy for me to add the duration of each activity - even if it's approximate, it doesn't matter that much. Watched a movie? - 2 hours. Worked on a site the whole morning? - 3 or 4 hours. And so on.

Another compromise was to get rid of inconsistent parameters that don't translate to every log type - for example, rating (which I used for movies, books, and albums) or the km property for running. And I think it's okay too, because in this new system we're gonna have a fixed number of arguments instead, which is gonna make usage of the system much easier and more streamlined.

Arguments

So, here are the arguments that I settled on after a long consideration:

  1. ID - identification number, assigned incrementally
  2. Date - log date, assigned automatically
  3. Sector - one of 4 main groups of activities: A, C, H, W
  4. Code - 3-letter code for activity (RUN, EDT, RDG, etc)
  5. Duration - time spent on activity, HHhMMm
  6. Entry - any string you want: what book you read / how many km you ran, etc

I found that this list of arguments is the most effective for generating great stats, while still being minimal and easy to remember/use at the same time. Shortly: ID is needed to use commands - basically, you can do stuff like del 0012 or dup 0184 to make quick operations with entries using only the command line. Date is obvious - by default it uses the system date when you add a new log, but if you add a log retrospectively with the command ret, you can set any date manually. Duration and entry are pretty obvious too, so let's talk about sectors and codes. Here's a quick explanation:

Sectors & Codes

So, I split all the log types into 4 main sectors:

  1. A - Action - anything you do, like this website, or the logging system, for example
  2. C - Consumption - watching stuff, reading stuff - passive activities
  3. H - Health - running, gym, hiking, and so on
  4. W - Work - basically anything you make money with

Each sector can contain as many codes as you want:

  1. A : GRD, PLN, LRN
  2. C : RDG, YTB, MUS, MOV, GMN
  3. H : RUN, HIK, GYM, WLK, CAL, MDT
  4. W : EDT

I thought about these sectors a lot and tried a lot of other ways to split everything, but this one seemed the most reasonable to me. Why do I need those sectors at all? The first reason - I want to generate general statistics, and my main goals are to check the balance between passive and active activities, check the balance between work and personal projects, and check how much time I spend on health compared to everything else. The second reason - this way I don't need to create a fixed list of codes (EDT, RUN, RDG...) and make a dictionary for them. Because without sectors, for the general stats I would need to assign each code to a sector anyway, and it would be much more complicated. And now I can add any log with a new code if I want to - for example, "H CLM" for climbing - and I don't need to update any files. It will automatically be included in all the stats and dashboards. I hope it makes sense!

UI overview

So, lets look at the main interface. By default it shows last 10 logs.


LOG / 21 ENTRIES / TOTAL 47h29m / 250524 / 
---------------------------------------------------------------------------------------
ID    Date    Sec    Code    Duration    Entry
----  ------  -----  ------  ----------  ----------------------------------------------
0021  250524  A      PLN     02h14m      Logging system - all scripts updated, finished
0020  250523  C      RDG     01h00m      Kafka on the Shore - Haruki Murakami (2002)
0019  250523  W      EDT     00h50m      ^#@%$!@^, !@%#$@
0018  250523  A      PLN     04h00m      Updated website dashboards
0017  250523  A      PLN     01h00m      Logging system - code refactoring
0016  250523  A      PLN     01h38m      Logging system - added sum, man, fixed ui
0015  250522  C      RDG     01h20m      Kafka on the Shore - Haruki Murakami (2002)
0014  250522  W      EDT     02h30m      #@$^%$# &%@# + &#^@
0013  250522  A      GRD     01h15m      Ivy cuttings repotting
0012  250522  A      PLN     04h00m      Logging system - working CLI prototype
---------------------------------------------------------------------------------------
plantay@fedora:~/plantayme/logbook-cli$ 

As you can see, I made 3 main parts of UI - status bar, log list and command line. To make it work similar to TUI, after each command the terminal window clears and displays all the elements updated - this way you won't end up with endless mess of commands and lists on the screen, everything is static in one place. Status bar shows general stats, program messages and filters. Nothing special here, so let's move on to the commands.

Commands

Here's a command list:

- add [sec] [code] [dur] ["act"]               Add a new log entry
- ret [date] [sec] [code] [dur] ["act"]        Add a retro log entry
- dup [id]                                     Duplicate a log by ID with current date
- del [id]                                     Delete a log by ID
- jmp [id] or [date]                           Jump to a log by ID or date
- flt [sector/date/code/entry]:---             Filter logs by category
- sum [period]                                 Show summary (total | year | month | week)
- man                                          Show manual

I hope everything here is clear too, I decided not to make too many commands and keep everything as simple as possible. We have add and ret to add logs, dup to repeat log with today's date, del to delete log, jmp for basic navigation, flt to filter logs by any parameter (or by several parameters), sum for simple stats and man to keep record of all the codes and commands. Everything for dashboard generation for this site is in the separate scripts for easier maintenance, so this tool is just for logging itself.

Project tree

Here's a project tree for those who interested:

├── logbook
│   ├── commands
│   │   ├── add.py
│   │   ├── dlt.py
│   │   ├── dup.py
│   │   ├── flt.py
│   │   ├── __init__.py
│   │   ├── jmp.py
│   │   ├── log.py
│   │   ├── man.py
│   │   └── sum.py
│   ├── __init__.py
│   ├── storage.py
│   └── utils.py
├── logbook.db
├── main.py
└── requirements.txt

Homepage dashboard

And here's the most interesting stuff! How we can use all that data to do analytics. The main goal of all this thing for me was to make cool dashboards for my website that I can use to track my progress and see how I can improve my life using all this stats. I created 2 scripts: one for homepage, and one for weeknotes.

Here are all the homepage dashboards. I render them separately to several .txt files so I can use CSS and stylize them how I want - make 2-column layouts and stuff like that. Originally, I made a lot more stats, but it was taking too much space, so I ended up cutting it down a lot.


[ SUM ] 21 logs recorded
[ SUM ] 47h29m logged time
[ AVG ] 02h15m avg session
[ MON ] 21 logs / 47h29m this month

[ A ] 26h07m ||||||||||||||||||||||||||||||
[ C ] 10h47m ||||||||||||
[ H ] 02h00m ||
[ W ] 08h35m |||||||||

[ RDG ] Kafka on the Shore - Haruki Murakami (2002)
[ MUS ] SUDS - The Great Overgrowth (2023)
[ MOV ] The Rehearsal - Nathan Fielder (2022)


The first block is called meta - it represents general statistics: total number of logs, hours, average session duration and short month stats. The second one is called sectors - it shows total amount of time spent on main sectors: Actions / Consumption / Health / Work. Good thing to see on the homepage to check if you're spending too much time on some things, like me with this logging system instead of working, haha. The third one is called now and shows last added logs for the book I read, movie I watched and music I listened to.

I think those dashboards are enough for personal website, though I wanted to add a lot more - but I really need to get my life back at this point. I spent too much time on it already, and I don't need to spend more - it already works great, at least much better than previous one.

Weeknote dashboard

And the second part of stats - dashboard that automatically generates after creating a weeknote. This one I like the most, it turned out so cool:


sum 21 logs / 47h29m logged time / 02h15m avg session

[ A ] 26h07m ||||||||||||||||||||||||||||||||||||||||||||||||||
[ C ] 10h47m ||||||||||||||||||||
[ H ] 02h00m |||
[ W ] 08h35m ||||||||||||||||

250524 : A PLN 02h14m Logging system - all scripts updated, finished
250523 : A PLN 01h38m Logging system - added sum, man, fixed ui
250523 : A PLN 01h00m Logging system - code refactoring
250523 : A PLN 04h00m Updated website dashboards

More entries

250523 : C RDG 01h00m Kafka on the Shore - Haruki Murakami (2002)
250522 : C MOV 03h20m The Rehearsal - Nathan Fielder (2022)
250522 : A PLN 04h00m Logging system - working CLI prototype
250522 : A GRD 01h15m Ivy cuttings repotting
250522 : C RDG 01h20m Kafka on the Shore - Haruki Murakami (2002)
250521 : C MOV 02h00m The Mule - Clint Eastwood (2018)
250521 : H WLK 02h00m Took a short morning walk
250521 : C YTB 01h07m GL;HF Podcast
250521 : A PLN 03h45m Logging system - TUI prototype
250520 : A PLN 04h55m Logging system design
250520 : A GRD 03h20m Terrarium build, watering
250520 : C MUS 00h40m SUDS - The Great Overgrowth (2023)
250520 : C RDG 01h20m Kafka on the Shore - Haruki Murakami (2002)


It also has 3 parts: the first one is short statistics from the week - number of logs, time spent and average session duration. Then we have the sector one, similar to the one on the homepage - it shows log distribution for the week. And the last one is the list of logs added during the week, except the work, since there's some personal info. By default it shows 4 last entries, but you can expand the list and it'll show all the logs. This one is very useful, because I can just open it before writing a weeknote and have a glance of stuff I did during the week. I really like how it looks!

Outro

So, here it is, in all the details I could remember in my disturbed state of mind, after sitting 24/7 in front of the screen for a few weeks! Of course, if something is still unclear and you have any questions, you can email me.

The main purpose of this post was not to show how I technically did it, but more to show the system itself - it was my biggest problem while researching. All the systems that I found were either too complicated or too simple, so this is my attempt to make a time-tracking system that can be easy to use (it takes less than a minute to log everything in the evening for me), and that can still give a lot of useful data that you can use in a big amount of ways.

Next:
Prev: