#journal #obsidian #markdown #journal-logging #logging

bin+lib obsidian-logging

A journaling/logging CLI that stores logs in Obsidian markdown files

16 stable releases

1.2.1 Oct 23, 2025
1.2.0 Oct 21, 2025
1.1.3 Sep 30, 2025
1.1.0 Aug 26, 2025
1.0.14 Jun 30, 2025

#252 in Text processing

Download history 60/week @ 2025-08-20 49/week @ 2025-08-27 3/week @ 2025-09-03 134/week @ 2025-09-10 8/week @ 2025-09-17 168/week @ 2025-09-24 110/week @ 2025-10-01 4/week @ 2025-10-08 68/week @ 2025-10-15 219/week @ 2025-10-22

288 downloads per month

MIT license

73KB
1K SLoC

Obsidian logging - Log to Obsidian Journal from command line

Crates.io Documentation License: MIT

This little utility written in Rust makes it possible to log directly to todays daily note from the linux command line.

License

This software is licensed under a combined MIT and SPPL license. It is basically a MIT license, but in order to be compliant you need to send me a postcard. Details in LICENSE.md

Installation

You can install obsidian-logging using cargo:

cargo install obsidian-logging

Or build from source:

git clone https://github.com/ljantzen/obsidian-logging
cd obsidian-logging
cargo build --release

Or download binaries directly from the github releases page.

Tip

Since obsidian-logging is quite a mouthful to type every time, it is recommended to create a short alias. E.g

alias q=` obsidian-logging`

(Note: the space before the program name stops the command from being entered into command history)

On Windows, the doskey command can be used to create a macro:

doskey q=obsidian-logging

Configuration file

Obsidian-logging reads ~/.config/obsidian-logging/obsidian-logging.yaml on startup. If it does not exist, obsidian-logging will create it and prompt for some of the values. This is a file that uses the yaml configuration format. See obsidian-logging.example.yaml for what can be configured.

Obsidian-logging looks for a marker that signifies where the log entries block will start. Log entries must be consecutive without empty lines. The marker is specified in the config file.

Category-specific section headers

The default block marker is specified in the configuration file with the property section_header.

Example configuration:

section_header: "## πŸ•—"

obsidian-logging can log to a number of different sections in the daily log. These are called log categories. You can define category-specific section headers in the config yaml using the pattern section_header_<category_name>. When using the -c or --category flag, obsidian-logging will look for a section header with this pattern and log entries to that section instead of the default section.

Example configuration:

section_header: "## πŸ•—"
section_header_work: "## πŸ’Ό Work"
section_header_personal: "## 🏠 Personal"
section_header_health: "## πŸ₯ Health"

So when you run obsidian-logging -c work "Meeting", the entry will be logged under the "## πŸ’Ό Work" section. If the category doesn't have a corresponding section header defined, entries will be logged to the default section specified by section_header.

Predefined Phrases

You can define common logging phrases in your configuration file to use with the -p or --phrase option. This allows you to create shorthand references for frequently used log entries.

Basic phrase configuration:

phrases:
  meeting: "Team meeting with stakeholders"
  gym: "Workout at the gym"
  lunch: "Lunch break"
  doctor: "Doctor appointment"

Phrases with argument expansion:

# Conjunction for {#} placeholder is automatically selected based on locale
# Supported locales: no/nb/nn (og), da (og), sv (och), de (und), fr (et), es (y), it (e), pt (e), ru (ΠΈ), ja (と), ko (와), zh (ε’Œ)
# Defaults to "and" for English or unsupported locales

phrases:
  # Simple phrases
  meeting: "Team meeting with stakeholders"
  gym: "Workout at the gym"
  
  # Phrases with argument expansion
  meeting_with: "Team meeting with {*}"           # All arguments
  call_with: "Phone call with {0}"               # First argument only
  project: "Working on {0}"                     # First argument only
  exercise: "Exercise: {*}"                     # All arguments
  travel: "Travel to {0}"                       # First argument only
  food: "Ate {*}"                               # All arguments
  
  # Phrases with {#} placeholder for comma-separated lists
  meeting_with: "Team meeting with {#}"          # "John and Jane" or "John, Jane and Bob"
  call_with: "Phone call with {#}"              # "Alice and Bob" or "Alice, Bob and Charlie"
  project_with: "Working on {#}"                # "Frontend and Backend"
  exercise_with: "Exercise: {#}"                # "Running and Swimming"

Usage examples:

# Basic phrases
obsidian-logging -p meeting
obsidian-logging -p gym -c health

# Phrases with arguments
obsidian-logging -p meeting_with John Smith     # "Team meeting with John Smith"
obsidian-logging -p call_with Alice            # "Phone call with Alice"
obsidian-logging -p project "Project Alpha"   # "Working on Project Alpha"
obsidian-logging -p exercise "Running 5km"    # "Exercise: Running 5km"

# Phrases with {#} placeholder for comma-separated lists
obsidian-logging -p meeting_with John Jane        # "Team meeting with John and Jane"
obsidian-logging -p call_with Alice Bob Charlie  # "Phone call with Alice, Bob and Charlie"
obsidian-logging -p project_with Frontend Backend # "Working on Frontend and Backend"

Environment variable

If specified, $OBSIDIAN_VAULT_DIR will override the vault value in obsidian-logging.yaml

Command line switches

No arguments

When invoking obsidian-logging without any arguments the entries of the current day, if any, will be listed. This is equivalent to obsidian-logging -l

No switches

When invoking the command obsidian-logging This is a log entry obsidian-logging will append the string This is a log entry to the default log section of the markdown daily note. A timestamp will be prepended according to the chosen list mode. If list mode is bullet, '- HH:mm ' is prepended to the log statement. If list mode is 'table', the log statement is wrapped in markdown table column separators: | HH:mm | log statement|

Usage Examples

# List today's entries
obsidian-logging

# Add a log entry to the default section
obsidian-logging "Had lunch with colleagues"

# Add an entry with a specific time
obsidian-logging -t 14:30 "Team standup meeting"

# Add entries to different categories
obsidian-logging -c work "Code review completed"
obsidian-logging -c personal "Gym workout - 45 minutes"
obsidian-logging -c health "Annual checkup scheduled"

# Combine category with time override
obsidian-logging -c work -t 9:00 "Daily standup"

# Use predefined phrases
obsidian-logging -p meeting                    # Basic phrase
obsidian-logging -p gym -c health             # Phrase with category
obsidian-logging -p meeting_with John Smith   # Phrase with arguments
obsidian-logging -p call_with Alice -t 14:30 # Phrase with arguments and time

# Read from stdin (useful for piping)
echo "Quick note" | obsidian-logging -S
cat notes.txt | obsidian-logging -c work -S

# List entries from previous days
obsidian-logging -b 1  # Yesterday's entries
obsidian-logging -b 7  # One week ago

# List entries by category
obsidian-logging -l -c work      # List only work entries
obsidian-logging -l -c personal  # List only personal entries
obsidian-logging -l -c work -c personal  # List work and personal entries
obsidian-logging -l -c all       # List entries from all categories
obsidian-logging -b 1 -c work    # List work entries from yesterday

# Edit today's file directly
obsidian-logging -e

-t or --time

The timestamp may be overridden by specifying the -t/--time HH:mm switch. Log entries are sorted chronologically before being added to the markdown file. If using the 12 hour clock format (time_format: 12 in the config file), the format is HH:mmA. For example 08:13PM.

-l or --list

You can list the current days log entries by specifying the -l option. If obsidian-logging is invoked without any arguments, this is the default action.

When combined with the -c or --category option, only entries from the specified category section will be listed. If no category-specific section header is found, entries from the default section will be shown. The -c option can be specified multiple times to list entries from multiple categories, or use -c all to list entries from all categories.

Examples:

obsidian-logging -l                    # List entries from default section
obsidian-logging -l -c work            # List entries from work category
obsidian-logging -l -c personal        # List entries from personal category
obsidian-logging -l -c work -c personal # List entries from work and personal categories
obsidian-logging -l -c all             # List entries from all categories
obsidian-logging -l -c unknown         # List entries from default section (fallback)

-b or --back

By specifying -b <number> you can go back in time and list the logs number of days ago. obsidian-logging -b 0 is the same as obsidian-logging -l. -b can be combined with -c.

-e or --edit

Invokes $EDITOR with todays file. Uses vim if $EDITOR is not set,

-f or --time-format

Specifies 12H or 24H time format. 24H is default. Overrides time_format in obsidian-logging.yaml. Combining 12-hour and 24 hour timestamps when adding logs may yield unpredictable results.

-s or --silent

Do not output anything, not even error messages

-h or --help

Print command line argument help

-T list mode

Specifies the list output mode when obsidian-logging -l is called. Valid arguments are -T bullet and -T table. Overrides the list mode in obsidian-logging.yaml configuration file

-v or --version

Outputs the current version string and exits execution

-S or --stdin

If specified, input will be read from stdin instead of command line arguments, allowing piping of log statements into the program. Carriage return or linefeed characters will be removed, and log statement will be logged as a single line.

-c or --category

Specifies a category for the log entry. The entry will be logged to a section identified by the section_header_<category> property in the configuration file. If no category-specific section header is found, the entry will be logged to the default section specified by section_header.

When used with the -l option, this flag can be specified multiple times to list entries from multiple categories. Use -c all to list entries from all categories.

Examples:

# Adding entries
obsidian-logging -c work "Team meeting at 2pm"
obsidian-logging -c personal "Gym workout"
obsidian-logging -c health "Doctor appointment"

# Listing entries
obsidian-logging -l -c work                    # List work entries only
obsidian-logging -l -c work -c personal        # List work and personal entries
obsidian-logging -l -c all                     # List entries from all categories

-p or --phrase

Use a predefined phrase from the configuration file with optional argument expansion. This allows you to define common logging phrases in your config and reference them with shorthand.

Argument Expansion Support:

  • {0}, {1}, {2}, etc. - Replace with specific argument by index
  • {*} - Replace with all arguments joined by spaces
  • {#} - Replace with all arguments in comma-separated list with proper conjunction

Examples:

# Basic phrase usage (no arguments)
obsidian-logging -p meeting
obsidian-logging -p gym -c health

# Phrase with argument expansion
obsidian-logging -p meeting_with John Smith        # "Team meeting with John Smith"
obsidian-logging -p call_with Alice               # "Phone call with Alice"
obsidian-logging -p project "Project Alpha"      # "Working on Project Alpha"

# Phrase with {#} placeholder for comma-separated lists
obsidian-logging -p meeting_with John Jane        # "Team meeting with John and Jane"
obsidian-logging -p call_with Alice Bob Charlie  # "Phone call with Alice, Bob and Charlie"
obsidian-logging -p project_with Frontend Backend # "Working on Frontend and Backend"

# Combine with other options
obsidian-logging -p meeting_with John -t 14:30    # With specific time
obsidian-logging -p doctor_with "Dr. Smith" -c health  # With category

Example Output

With the category functionality, your daily notes can be organized into different sections. Here's an example of what a daily note might look like:

# 2024-01-15

## πŸ•—

* 08:30 Morning coffee
* 12:00 Lunch break

## πŸ’Ό Work

* 09:00 Daily standup meeting
* 10:30 Code review completed
* 14:00 Client presentation

## 🏠 Personal

* 18:00 Gym workout - 45 minutes
* 19:30 Dinner with family

## πŸ₯ Health

* 11:00 Doctor appointment
* 16:00 Picked up prescription

Screenshots

Bullet mode

image

Table mode

image

Contact info

https://mas.to/@jantzten

https://bsky.app/profile/leif.jantzen.no

Dependencies

~8–21MB
~215K SLoC