Standardize logging across codebase with consistent structured format

This commit is contained in:
Jeffrey Paul 2025-05-22 06:54:30 -07:00
parent 634cc45f3a
commit b8f2ea7b7b
4 changed files with 41 additions and 22 deletions

4
llm.go
View File

@ -25,7 +25,7 @@ type SummaryResult struct {
// articleSummarizer checks for articles without summaries every 10 seconds and processes them in batches // articleSummarizer checks for articles without summaries every 10 seconds and processes them in batches
func articleSummarizer(shutdown chan struct{}, ollamaURL, ollamaModel string) { func articleSummarizer(shutdown chan struct{}, ollamaURL, ollamaModel string) {
fmt.Fprintf(os.Stderr, "[summarizer] Starting article summarizer (interval: %s)\n", SUMMARIZE_INTERVAL) logInfo("summarizer", fmt.Sprintf("Starting article summarizer (interval: %s)", SUMMARIZE_INTERVAL), nil)
ticker := time.NewTicker(SUMMARIZE_INTERVAL) ticker := time.NewTicker(SUMMARIZE_INTERVAL)
defer ticker.Stop() defer ticker.Stop()
@ -35,7 +35,7 @@ func articleSummarizer(shutdown chan struct{}, ollamaURL, ollamaModel string) {
case <-ticker.C: case <-ticker.C:
summarizeArticles(ollamaURL, ollamaModel) summarizeArticles(ollamaURL, ollamaModel)
case <-shutdown: case <-shutdown:
fmt.Fprintf(os.Stderr, "[summarizer] Shutting down article summarizer\n") logInfo("summarizer", "Shutting down article summarizer", nil)
return return
} }
} }

24
main.go
View File

@ -3,7 +3,6 @@ package main
import ( import (
"database/sql" "database/sql"
"flag" "flag"
"fmt"
"log" "log"
"os" "os"
"os/signal" "os/signal"
@ -25,7 +24,9 @@ var (
) )
func main() { func main() {
fmt.Fprintf(os.Stderr, "[%s] starting gomeshalerter\n", runStart.Format("15:04:05")) logInfo("main", "Starting gomeshalerter", map[string]interface{}{
"timestamp": runStart.Format("15:04:05"),
})
setupLogging() setupLogging()
defer flushLog() defer flushLog()
@ -37,12 +38,14 @@ func main() {
// Define a cleanup function to properly close resources // Define a cleanup function to properly close resources
cleanup := func() { cleanup := func() {
fmt.Fprintf(os.Stderr, "[shutdown] Closing database...\n") logInfo("shutdown", "Closing database", nil)
if err := db.Close(); err != nil { if err := db.Close(); err != nil {
fmt.Fprintf(os.Stderr, "[shutdown] Error closing database: %v\n", err) logInfo("shutdown", "Error closing database", map[string]interface{}{
"error": err.Error(),
})
} }
flushLog() flushLog()
fmt.Fprintf(os.Stderr, "[shutdown] Cleanup complete\n") logInfo("shutdown", "Cleanup complete", nil)
} }
// Ensure cleanup runs on normal exit // Ensure cleanup runs on normal exit
defer cleanup() defer cleanup()
@ -57,7 +60,10 @@ func main() {
ollamaURL = "http://localhost:11434" // Default Ollama server URL ollamaURL = "http://localhost:11434" // Default Ollama server URL
} }
fmt.Fprintf(os.Stderr, "[ollama] Using model: %s at %s\n", ollamaModel, ollamaURL) logInfo("ollama", "Using model", map[string]interface{}{
"model": ollamaModel,
"url": ollamaURL,
})
// Replace --broadcast flag with --dry-run flag (default is to broadcast) // Replace --broadcast flag with --dry-run flag (default is to broadcast)
dryRun := flag.Bool("dry-run", false, "don't actually send to meshtastic, just print what would be sent") dryRun := flag.Bool("dry-run", false, "don't actually send to meshtastic, just print what would be sent")
@ -75,9 +81,9 @@ func main() {
go func() { go func() {
<-sigChan <-sigChan
fmt.Fprintf(os.Stderr, "[shutdown] Received signal, performing cleanup before exit...\n") logInfo("shutdown", "Received signal, performing cleanup before exit", nil)
cleanup() cleanup()
fmt.Fprintf(os.Stderr, "[shutdown] Exiting...\n") logInfo("shutdown", "Exiting", nil)
os.Exit(0) // Exit after cleanup os.Exit(0) // Exit after cleanup
}() }()
@ -118,5 +124,5 @@ func main() {
// Wait for all goroutines to finish // Wait for all goroutines to finish
wg.Wait() wg.Wait()
fmt.Fprintf(os.Stderr, "[shutdown] All goroutines stopped, exiting...\n") logInfo("shutdown", "All goroutines stopped, exiting", nil)
} }

21
rss.go
View File

@ -3,7 +3,6 @@ package main
import ( import (
"fmt" "fmt"
"net/http" "net/http"
"os"
"sync" "sync"
"time" "time"
@ -53,7 +52,7 @@ var feeds = map[string]string{
// rssFeedChecker checks RSS feeds every 15 minutes and adds new articles to the database // rssFeedChecker checks RSS feeds every 15 minutes and adds new articles to the database
func rssFeedChecker(shutdown chan struct{}, ollamaURL, ollamaModel string) { func rssFeedChecker(shutdown chan struct{}, ollamaURL, ollamaModel string) {
fmt.Fprintf(os.Stderr, "[rss] Starting RSS feed checker (interval: %s)\n", RSS_CHECK_INTERVAL) logInfo("rss", fmt.Sprintf("Starting RSS feed checker (interval: %s)", RSS_CHECK_INTERVAL), nil)
// Run immediately on startup // Run immediately on startup
checkRSSFeeds() checkRSSFeeds()
@ -67,7 +66,7 @@ func rssFeedChecker(shutdown chan struct{}, ollamaURL, ollamaModel string) {
case <-ticker.C: case <-ticker.C:
checkRSSFeeds() checkRSSFeeds()
case <-shutdown: case <-shutdown:
fmt.Fprintf(os.Stderr, "[rss] Shutting down RSS feed checker\n") logInfo("rss", "Shutting down RSS feed checker", nil)
return return
} }
} }
@ -160,13 +159,23 @@ func fetchAllFeedsParallel(now time.Time) []Article {
logEvent("rss_fetch_result", details) logEvent("rss_fetch_result", details)
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "[rss] FAIL %-15s (%s) [%.2fs] ERR: %v\n", source, url, duration.Seconds(), err) logInfo("rss", "Feed fetch failed", map[string]interface{}{
"source": source,
"url": url,
"duration": duration.Seconds(),
"error": err.Error(),
})
results <- fetchResult{Source: source, URL: url, Err: err, Duration: duration, HTTPStatus: httpStatus} results <- fetchResult{Source: source, URL: url, Err: err, Duration: duration, HTTPStatus: httpStatus}
return return
} }
fmt.Fprintf(os.Stderr, "[rss] OK %-15s (%s) [%.2fs] HTTP %d, items: %d\n", logInfo("rss", "Feed fetch succeeded", map[string]interface{}{
source, url, duration.Seconds(), httpStatus, len(feed.Items)) "source": source,
"url": url,
"duration": duration.Seconds(),
"status": httpStatus,
"items": len(feed.Items),
})
results <- fetchResult{ results <- fetchResult{
Source: source, Source: source,

View File

@ -6,6 +6,7 @@ import (
"encoding/hex" "encoding/hex"
"encoding/json" "encoding/json"
"fmt" "fmt"
"log"
"os" "os"
"sort" "sort"
"time" "time"
@ -348,8 +349,7 @@ func setupLogging() {
var err error var err error
logFile, err = os.Create(logPath) logFile, err = os.Create(logPath)
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "could not create log file: %v\n", err) log.Fatalf("Could not create log file: %v", err)
os.Exit(1)
} }
} }
@ -395,7 +395,7 @@ func logEvent(event string, details map[string]interface{}) {
// Store log in database // Store log in database
logBytes, err := json.Marshal(entry) logBytes, err := json.Marshal(entry)
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "Error marshaling log entry: %v\n", err) log.Printf("Error marshaling log entry: %v", err)
return return
} }
@ -407,7 +407,7 @@ func logEvent(event string, details map[string]interface{}) {
_, err = db.Exec("INSERT INTO logs (id, timestamp, log) VALUES (?, ?, ?)", _, err = db.Exec("INSERT INTO logs (id, timestamp, log) VALUES (?, ?, ?)",
id, timestamp, string(logBytes)) id, timestamp, string(logBytes))
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "Error storing log in database: %v\n", err) log.Printf("Error storing log in database: %v", err)
} }
} }
@ -453,7 +453,11 @@ func cleanupOldLogs() error {
rowsDeleted, _ := result.RowsAffected() rowsDeleted, _ := result.RowsAffected()
if rowsDeleted > 0 { if rowsDeleted > 0 {
fmt.Fprintf(os.Stderr, "[logs] Deleted %d log entries older than one month\n", rowsDeleted) logInfo("logs", "Deleted old log entries", map[string]interface{}{
"count": rowsDeleted,
"olderThan": "1 month",
"cutoffDate": cutoff.Format(time.RFC3339),
})
} }
return nil return nil