taldir

Directory service to resolve wallet mailboxes by messenger addresses
Log | Files | Refs | Submodules | README | LICENSE

commit d034fde5da9851e09d3acffd015576ad9115a468
parent e7f2072ae60b28c8465fd8dd84f56fd54f5b24a6
Author: Martin Schanzenbach <schanzen@gnunet.org>
Date:   Fri,  8 Aug 2025 12:46:39 +0200

refactor logger

Diffstat:
Mpkg/taldir/command_validator.go | 18+++++++++---------
Mpkg/taldir/config.go | 16----------------
Mpkg/taldir/disseminator_gns.go | 10+++++-----
Apkg/taldir/logger.go | 37+++++++++++++++++++++++++++++++++++++
Mpkg/taldir/taldir.go | 84+++++++++++++++++++++++++++++++++++++------------------------------------------
Mpkg/taldir/validator.go | 4+---
6 files changed, 91 insertions(+), 78 deletions(-)

diff --git a/pkg/taldir/command_validator.go b/pkg/taldir/command_validator.go @@ -19,18 +19,18 @@ package taldir import ( - "html/template" - "regexp" "fmt" + "html/template" "os/exec" + "regexp" ) type CommandValidator struct { - // Name + // Name name string - // Config + // Config config *TaldirConfig // Validator alias regex @@ -88,13 +88,13 @@ func (t *CommandValidator) RegistrationStart(topic string, link string, message return nil } -func make_command_validator (cfg *TaldirConfig, name string, landingPageTpl *template.Template) CommandValidator { +func make_command_validator(cfg *TaldirConfig, name string, landingPageTpl *template.Template) CommandValidator { sec := cfg.Ini.Section("taldir-validator-" + name) return CommandValidator{ - name: name, - config: cfg, - landingPageTpl: landingPageTpl, + name: name, + config: cfg, + landingPageTpl: landingPageTpl, validAliasRegex: sec.Key("valid_alias_regex").MustString(""), - command: sec.Key("command").MustString(""), + command: sec.Key("command").MustString(""), } } diff --git a/pkg/taldir/config.go b/pkg/taldir/config.go @@ -43,19 +43,3 @@ type TaldirConfig struct { // The loglevel to use Loglevel LogLevel } - -type LogLevel int - -const ( - LogError LogLevel = iota - LogWarning - LogInfo - LogDebug -) - -var LoglevelStringMap = map[LogLevel]string{ - LogDebug: "DEBUG", - LogError: "ERROR", - LogWarning: "WARN", - LogInfo: "INFO", -} diff --git a/pkg/taldir/disseminator_gns.go b/pkg/taldir/disseminator_gns.go @@ -29,21 +29,21 @@ type GnsDisseminator struct { config *TaldirConfig } -func (d *GnsDisseminator) gns_check_is_disseminated (e *Entry) bool { +func (d *GnsDisseminator) gns_check_is_disseminated(e *Entry) bool { path, err := exec.LookPath("gnunet-gns") if err != nil { return false } zone := d.config.Ini.Section("taldir-disseminator-gns").Key("zone").MustString("taldir") - out, err := exec.Command(path, "--lookup", e.HsAddress + "." + zone, "--type", "TXT").Output() + out, err := exec.Command(path, "--lookup", e.HsAddress+"."+zone, "--type", "TXT").Output() if err != nil { return false } - return strings.Contains(string(out), "TXT: `" + e.TargetUri + "'") + return strings.Contains(string(out), "TXT: `"+e.TargetUri+"'") } func (d *GnsDisseminator) DisseminateStop(e *Entry) error { - if ! d.gns_check_is_disseminated(e) { + if !d.gns_check_is_disseminated(e) { return nil } path, err := exec.LookPath("gnunet-namestore") @@ -86,7 +86,7 @@ func (d *GnsDisseminator) IsEnabled() bool { func make_gns_disseminator(cfg *TaldirConfig) GnsDisseminator { d := GnsDisseminator{ - config: cfg, + config: cfg, } return d } diff --git a/pkg/taldir/logger.go b/pkg/taldir/logger.go @@ -0,0 +1,37 @@ +package taldir + +import ( + "log" +) + +type LogLevel int + +const ( + LogError LogLevel = iota + LogWarning + LogInfo + LogDebug +) + +var LoglevelStringMap = map[LogLevel]string{ + LogDebug: "DEBUG", + LogError: "ERROR", + LogWarning: "WARN", + LogInfo: "INFO", +} + +type TaldirLogger struct { + // Internal logger + InternalLogger *log.Logger + + // Loglevel + logLevel LogLevel +} + +func (l *TaldirLogger) Logf(loglevel LogLevel, fmt string, args ...any) { + if loglevel > l.logLevel { + return + } + l.InternalLogger.SetPrefix("taler-directory - " + LoglevelStringMap[loglevel] + " ") + l.InternalLogger.Printf(fmt, args...) +} diff --git a/pkg/taldir/taldir.go b/pkg/taldir/taldir.go @@ -124,7 +124,7 @@ type Taldir struct { I18n *i18n.I18n // Logger - Logger *log.Logger + Logger TaldirLogger } // VersionResponse is the JSON response of the /config endpoint @@ -305,7 +305,7 @@ func (t *Taldir) disseminateStop(e Entry) error { for _, d := range t.Disseminators { err := d.DisseminateStop(&e) if err != nil { - t.Logf(LogWarning, "Dissemination stop failed for disseminator `%s' and entry `%s'", d.Name(), e.HsAddress) + t.Logger.Logf(LogWarning, "Dissemination stop failed for disseminator `%s' and entry `%s'", d.Name(), e.HsAddress) } } return nil @@ -316,7 +316,7 @@ func (t *Taldir) disseminateStart(e Entry) { for _, d := range t.Disseminators { err := d.DisseminateStart(&e) if err != nil { - t.Logf(LogWarning, "Dissemination start failed for disseminator `%s' and entry `%s': %v", d.Name(), e.HsAddress, err) + t.Logger.Logf(LogWarning, "Dissemination start failed for disseminator `%s' and entry `%s': %v", d.Name(), e.HsAddress, err) } } } @@ -373,20 +373,20 @@ func (t *Taldir) validationRequest(w http.ResponseWriter, r *http.Request) { return } } else { - t.Logf(LogDebug, "New solution timeframe set.") + t.Logger.Logf(LogDebug, "New solution timeframe set.") validation.LastSolutionTimeframeStart = time.Now() validation.SolutionAttemptCount = 1 } t.Db.Save(&validation) expectedSolution := util.GenerateSolution(validation.TargetUri, validation.Challenge) - t.Logf(LogDebug, "Expected solution: `%s', given: `%s'\n", expectedSolution, confirm.Solution) + t.Logger.Logf(LogDebug, "Expected solution: `%s', given: `%s'\n", expectedSolution, confirm.Solution) if confirm.Solution != expectedSolution { w.WriteHeader(http.StatusForbidden) return } err = t.Db.Delete(&validation).Error if err != nil { - t.Logf(LogError, "Error deleting validation") + t.Logger.Logf(LogError, "Error deleting validation") w.WriteHeader(http.StatusInternalServerError) return } @@ -397,7 +397,7 @@ func (t *Taldir) validationRequest(w http.ResponseWriter, r *http.Request) { err = t.Db.First(&entry, "hs_address = ?", entry.HsAddress).Error if err == nil { if validation.TargetUri == "" { - t.Logf(LogDebug, "Deleted entry for '%s´\n", entry.HsAddress) + t.Logger.Logf(LogDebug, "Deleted entry for '%s´\n", entry.HsAddress) err = t.Db.Delete(&entry).Error if err != nil { w.WriteHeader(http.StatusInternalServerError) @@ -410,7 +410,7 @@ func (t *Taldir) validationRequest(w http.ResponseWriter, r *http.Request) { } } else { if validation.TargetUri == "" { - t.Logf(LogWarning, "Validated a deletion request but no entry found for `%s'\n", entry.HsAddress) + t.Logger.Logf(LogWarning, "Validated a deletion request but no entry found for `%s'\n", entry.HsAddress) } else { err = t.Db.Create(&entry).Error if err != nil { @@ -504,7 +504,7 @@ func (t *Taldir) registerRequest(w http.ResponseWriter, r *http.Request) { } rateLimited, err := t.isRateLimited(hAddress) if nil != err { - t.Logf(LogError, "Error checking rate limit! %v", err) + t.Logger.Logf(LogError, "Error checking rate limit! %v", err) w.WriteHeader(http.StatusInternalServerError) return } else if rateLimited { @@ -562,7 +562,7 @@ func (t *Taldir) registerRequest(w http.ResponseWriter, r *http.Request) { if paytoErr != nil { fmt.Println(paytoErr) w.WriteHeader(http.StatusInternalServerError) - t.Logf(LogError, paytoErr.Error()+"\n") + t.Logger.Logf(LogError, paytoErr.Error()+"\n") return } if len(payto) != 0 { @@ -575,7 +575,7 @@ func (t *Taldir) registerRequest(w http.ResponseWriter, r *http.Request) { } err = t.Db.Save(&validation).Error if err != nil { - t.Logf(LogError, err.Error()+"\n") + t.Logger.Logf(LogError, err.Error()+"\n") w.WriteHeader(500) return } @@ -584,7 +584,7 @@ func (t *Taldir) registerRequest(w http.ResponseWriter, r *http.Request) { message := t.I18n.GetLocale(r).GetMessage("taldirRegMessage", link) err = validator.RegistrationStart(topic, link, message, req.Address, validation.Challenge) if err != nil { - t.Logf(LogError, err.Error()+"\n") + t.Logger.Logf(LogError, err.Error()+"\n") t.Db.Delete(&validation) w.WriteHeader(500) return @@ -630,7 +630,7 @@ func (t *Taldir) validationPage(w http.ResponseWriter, r *http.Request) { return } if vars["challenge"] != validation.Challenge { - t.Logf(LogWarning, "Solution does not match challenge!\n") + t.Logger.Logf(LogWarning, "Solution does not match challenge!\n") w.WriteHeader(400) return } @@ -647,14 +647,14 @@ func (t *Taldir) validationPage(w http.ResponseWriter, r *http.Request) { expectedHAddress := util.Base32CrockfordEncode(h.Sum(nil)) if expectedHAddress != validation.HAddress { - t.Logf(LogWarning, "Address does not match challenge!\n") + t.Logger.Logf(LogWarning, "Address does not match challenge!\n") w.WriteHeader(400) return } // FIXME: This is kind of broken and probably requires wallet support/integration first if validation.RequiresPayment { - t.Logf(LogWarning, "Validation requires payment\n") + t.Logger.Logf(LogWarning, "Validation requires payment\n") walletLink = "taler://taldir/" + vars["h_address"] + "/" + vars["challenge"] + "-wallet" png, err = qrcode.Encode(walletLink, qrcode.Medium, 256) if err != nil { @@ -789,7 +789,7 @@ func (t *Taldir) methodLookupResultPage(w http.ResponseWriter, r *http.Request) emsg := "" found := false if nil != err { - t.Logf(LogWarning, "Not a valid alias\n") + t.Logger.Logf(LogWarning, "Not a valid alias\n") emsg = t.I18n.GetLocale(r).GetMessage("aliasInvalid", alias) http.Redirect(w, r, fmt.Sprintf("/landing/"+val.Name()+"?error=%s", emsg), http.StatusSeeOther) return @@ -799,7 +799,7 @@ func (t *Taldir) methodLookupResultPage(w http.ResponseWriter, r *http.Request) hsAddress := saltHAddress(hAddress, t.Salt) err = t.Db.First(&entry, "hs_address = ?", hsAddress).Error if err != nil { - t.Logf(LogError, "`%s` not found.\n", hAddress) + t.Logger.Logf(LogError, "`%s` not found.\n", hAddress) } else { found = true } @@ -887,7 +887,7 @@ func (t *Taldir) getFileName(relativeFileName string) string { if errors.Is(err, os.ErrNotExist) { _, err := os.Stat(t.Cfg.Datahome + "/" + relativeFileName) if errors.Is(err, os.ErrNotExist) { - t.Logf(LogError, "Tried fallback not found %s\n", t.Cfg.Datahome+"/"+relativeFileName) + t.Logger.Logf(LogError, "Tried fallback not found %s\n", t.Cfg.Datahome+"/"+relativeFileName) return "" } return t.Cfg.Datahome + "/" + relativeFileName @@ -895,18 +895,12 @@ func (t *Taldir) getFileName(relativeFileName string) string { return relativeFileName } -func (t *Taldir) Logf(loglevel LogLevel, fmt string, args ...any) { - if loglevel > t.Cfg.Loglevel { - return - } - t.Logger.SetPrefix("taler-directory - " + LoglevelStringMap[loglevel] + " ") - t.Logger.Printf(fmt, args...) -} - // Initialize the Taldir instance with cfgfile func (t *Taldir) Initialize(cfg TaldirConfig) { t.Cfg = cfg - t.Logger = log.New(os.Stdout, "taler-directory:", log.LstdFlags) + t.Logger = TaldirLogger{ + InternalLogger: log.New(os.Stdout, "taler-directory:", log.LstdFlags), + } // FIXME localedir i18n, err := i18n.New(i18n.Glob("./locales/*/*", i18n.LoaderConfig{ // Set custom functions per locale! @@ -929,23 +923,23 @@ func (t *Taldir) Initialize(cfg TaldirConfig) { continue } if !sec.HasKey("enabled") { - t.Logger.Printf("`enabled` key in section `[%s]` not found, disabling validator.\n", sec.Name()) + t.Logger.Logf(LogWarning, "`enabled` key in section `[%s]` not found, disabling validator.\n", sec.Name()) continue } if !sec.HasKey("type") { - t.Logger.Printf("`type` key in section `[%s]` not found, disabling validator.\n", sec.Name()) + t.Logger.Logf(LogWarning, "`type` key in section `[%s]` not found, disabling validator.\n", sec.Name()) continue } vname := strings.TrimPrefix(sec.Name(), "taldir-validator-") vlandingPageTplFile := sec.Key("registration_page").MustString(t.getFileName("web/templates/landing_" + vname + ".html")) vlandingPageTpl, err := template.ParseFiles(vlandingPageTplFile, navTplFile, footerTplFile) if err != nil { - t.Logger.Printf("`%s` template not found, disabling validator `%s`.\n", vlandingPageTplFile, vname) + t.Logger.Logf(LogWarning, "`%s` template not found, disabling validator `%s`.\n", vlandingPageTplFile, vname) continue } v := make_command_validator(&cfg, vname, vlandingPageTpl) if v.IsEnabled() { - t.Logger.Printf("`%s` validator disabled.\n", vname) + t.Logger.Logf(LogInfo, "`%s` validator disabled.\n", vname) t.Validators[vname] = &v } } @@ -953,7 +947,7 @@ func (t *Taldir) Initialize(cfg TaldirConfig) { gnsdisseminator := make_gns_disseminator(&cfg) if gnsdisseminator.IsEnabled() { t.Disseminators[gnsdisseminator.Name()] = &gnsdisseminator - t.Logger.Printf("Disseminator `%s' enabled.\n", gnsdisseminator.Name()) + t.Logger.Logf(LogInfo, "Disseminator `%s' enabled.\n", gnsdisseminator.Name()) } t.ChallengeBytes = cfg.Ini.Section("taldir").Key("challenge_bytes").MustInt(16) t.ValidationInitiationMax = cfg.Ini.Section("taldir").Key("validation_initiation_max").MustInt64(3) @@ -963,14 +957,14 @@ func (t *Taldir) Initialize(cfg TaldirConfig) { t.ValidPMSRegex = cfg.Ini.Section("taldir").Key("valid_payment_system_address_regex").MustString(".*") t.ValidationTimeframe, err = time.ParseDuration(validationTTLStr) if err != nil { - t.Logger.Fatal(err) + t.Logger.InternalLogger.Fatal(err) os.Exit(1) } retryTimeframeStr := cfg.Ini.Section("taldir").Key("solution_attempt_timeframe").MustString("1h") t.SolutionTimeframe, err = time.ParseDuration(retryTimeframeStr) if err != nil { - t.Logger.Fatal(err) + t.Logger.InternalLogger.Fatal(err) os.Exit(1) } t.MonthlyFee = cfg.Ini.Section("taldir").Key("monthly_fee").MustString("KUDOS:0") @@ -989,52 +983,52 @@ func (t *Taldir) Initialize(cfg TaldirConfig) { panic(err) } if cfg.Ini.Section("taldir").Key("purge_mappings_on_startup_dangerous").MustBool(false) { - t.Logger.Println("DANGER Purging mappings!") + t.Logger.Logf(LogWarning, "DANGER Purging mappings!") tx := t.Db.Where("1 = 1").Delete(&Entry{}) - t.Logger.Printf("Deleted %d entries.\n", tx.RowsAffected) + t.Logger.Logf(LogDebug, "Deleted %d entries.\n", tx.RowsAffected) } // Clean up validations validationExpStr := cfg.Ini.Section("taldir").Key("validation_expiration").MustString("24h") validationExp, err := time.ParseDuration(validationExpStr) if err != nil { - t.Logger.Fatal(err) + t.Logger.InternalLogger.Fatal(err) os.Exit(1) } go func() { for { tx := t.Db.Where("created_at < ?", time.Now().Add(-validationExp)).Delete(&Validation{}) - t.Logger.Printf("Cleaned up %d stale validations.\n", tx.RowsAffected) + t.Logger.Logf(LogInfo, "Cleaned up %d stale validations.\n", tx.RowsAffected) time.Sleep(validationExp) } }() imprintTplFile := cfg.Ini.Section("taldir").Key("imprint_page").MustString(t.getFileName("web/templates/imprint.html")) t.ImprintTpl, err = template.ParseFiles(imprintTplFile, navTplFile, footerTplFile) if err != nil { - t.Logger.Fatal(err) + t.Logger.InternalLogger.Fatal(err) os.Exit(1) } validationLandingTplFile := cfg.Ini.Section("taldir").Key("validation_landing").MustString(t.getFileName("web/templates/validation_landing.html")) t.ValidationTpl, err = template.ParseFiles(validationLandingTplFile, navTplFile, footerTplFile) if err != nil { - t.Logger.Fatal(err) + t.Logger.InternalLogger.Fatal(err) os.Exit(1) } landingTplFile := cfg.Ini.Section("taldir").Key("landing_page").MustString(t.getFileName("web/templates/landing.html")) t.LandingPageTpl, err = template.ParseFiles(landingTplFile, navTplFile, footerTplFile) if err != nil { - t.Logger.Fatal(err) + t.Logger.InternalLogger.Fatal(err) os.Exit(1) } lookupResultTplFile := cfg.Ini.Section("taldir").Key("lookup_result_page").MustString(t.getFileName("web/templates/lookup_result.html")) t.LookupResultPageTpl, err = template.ParseFiles(lookupResultTplFile, navTplFile, footerTplFile) if err != nil { - t.Logger.Fatal(err) + t.Logger.InternalLogger.Fatal(err) os.Exit(1) } aboutTplFile := cfg.Ini.Section("taldir").Key("about_page").MustString(t.getFileName("web/templates/about.html")) t.AboutPageTpl, err = template.ParseFiles(aboutTplFile, navTplFile, footerTplFile) if err != nil { - t.Logger.Fatal(err) + t.Logger.InternalLogger.Fatal(err) os.Exit(1) } t.Salt = os.Getenv("TALDIR_SALT") @@ -1046,12 +1040,12 @@ func (t *Taldir) Initialize(cfg TaldirConfig) { registrationCost, _ := talerutil.ParseAmount(t.MonthlyFee) merchConfig, err := t.Merchant.GetConfig() if err != nil { - t.Logger.Fatal(err) + t.Logger.InternalLogger.Fatal(err) os.Exit(1) } currencySpec, currencySupported := merchConfig.Currencies[registrationCost.Currency] for !currencySupported { - t.Logger.Fatalf("Currency `%s' not supported by merchant!\n", registrationCost.Currency) + t.Logger.InternalLogger.Fatalf("Currency `%s' not supported by merchant!\n", registrationCost.Currency) os.Exit(1) } t.CurrencySpec = currencySpec diff --git a/pkg/taldir/validator.go b/pkg/taldir/validator.go @@ -44,10 +44,8 @@ type Validator interface { LandingPageTpl() *template.Template // Is alias valid - IsAliasValid(alias string) error + IsAliasValid(alias string) error // Start registration RegistrationStart(topic string, link string, message string, address string, challenge string) error } - -