mirror of
https://github.com/getAlby/hub.git
synced 2026-08-13 12:33:39 +02:00
feat: add bark logger
This commit is contained in:
parent
a4dec48322
commit
5c23375c08
7 changed files with 146 additions and 0 deletions
|
|
@ -6,6 +6,8 @@ AUTO_LINK_ALBY_ACCOUNT=false
|
||||||
|
|
||||||
# Optionally set LDK debug log level to get more info
|
# Optionally set LDK debug log level to get more info
|
||||||
#LDK_LOG_LEVEL=5
|
#LDK_LOG_LEVEL=5
|
||||||
|
# Optionally set Bark debug log level to get more info
|
||||||
|
#BARK_LOG_LEVEL=5
|
||||||
# Optionally set Main application debug log level to get more info
|
# Optionally set Main application debug log level to get more info
|
||||||
#LOG_LEVEL=5
|
#LOG_LEVEL=5
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -292,6 +292,7 @@ Bark connects to an [Ark](https://second.tech/) server. It can be configured via
|
||||||
- `BARK_SERVER`: the Ark server URL. For signet use `https://ark.signet.2nd.dev`
|
- `BARK_SERVER`: the Ark server URL. For signet use `https://ark.signet.2nd.dev`
|
||||||
- `BARK_ESPLORA_SERVER`: the Esplora server URL used for chain data. For signet use `https://esplora.signet.2nd.dev`.
|
- `BARK_ESPLORA_SERVER`: the Esplora server URL used for chain data. For signet use `https://esplora.signet.2nd.dev`.
|
||||||
- `BARK_SERVER_ACCESS_TOKEN`: an optional access token required by the Ark server (pre-public mainnet launch).
|
- `BARK_SERVER_ACCESS_TOKEN`: an optional access token required by the Ark server (pre-public mainnet launch).
|
||||||
|
- `BARK_LOG_LEVEL`: Log level for Bark. Higher is more verbose. Default: 3. This is separate from the main application log level, allowing you to enable more verbose Bark logging (e.g., level 4 or 5) without enabling verbose logging for the entire application.
|
||||||
|
|
||||||
### Alby OAuth
|
### Alby OAuth
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,7 @@ type AppConfig struct {
|
||||||
BarkServer string `envconfig:"BARK_SERVER" default:"https://ark.second.tech"`
|
BarkServer string `envconfig:"BARK_SERVER" default:"https://ark.second.tech"`
|
||||||
BarkEsploraServer string `envconfig:"BARK_ESPLORA_SERVER" default:"https://mempool.second.tech/api"`
|
BarkEsploraServer string `envconfig:"BARK_ESPLORA_SERVER" default:"https://mempool.second.tech/api"`
|
||||||
BarkServerAccessToken string `envconfig:"BARK_SERVER_ACCESS_TOKEN"`
|
BarkServerAccessToken string `envconfig:"BARK_SERVER_ACCESS_TOKEN"`
|
||||||
|
BarkLogLevel string `envconfig:"BARK_LOG_LEVEL" default:"3"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *AppConfig) IsDefaultClientId() bool {
|
func (c *AppConfig) IsDefaultClientId() bool {
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
@ -50,6 +51,12 @@ type Config struct {
|
||||||
// ServerAccessToken is an optional access token required by some Ark
|
// ServerAccessToken is an optional access token required by some Ark
|
||||||
// servers (currently used to gate mainnet access ahead of a public launch).
|
// servers (currently used to gate mainnet access ahead of a public launch).
|
||||||
ServerAccessToken string
|
ServerAccessToken string
|
||||||
|
// LogLevel is the logrus level (as an int string, e.g. "3" for Info) used
|
||||||
|
// for bark's own internal logs. Defaults to Info if empty/unparseable.
|
||||||
|
LogLevel string
|
||||||
|
// LogToFile controls whether bark's logs are also written to a dedicated
|
||||||
|
// bark.log file alongside the other backend logs.
|
||||||
|
LogToFile bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type BarkService struct {
|
type BarkService struct {
|
||||||
|
|
@ -103,6 +110,14 @@ func NewBarkService(ctx context.Context, eventPublisher events.EventPublisher, w
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Forward bark's internal logs into a dedicated logger. Done before opening
|
||||||
|
// the wallet so any logs emitted during open are captured.
|
||||||
|
logLevel, err := strconv.Atoi(config.LogLevel)
|
||||||
|
if err != nil {
|
||||||
|
logLevel = int(logrus.InfoLevel)
|
||||||
|
}
|
||||||
|
installBarkLogger(logrus.Level(logLevel), config.LogToFile, workDir)
|
||||||
|
|
||||||
// Usually, you have two wait 2 blocks. You can set nb_min_round_confirmations=0 to make it go faster.
|
// Usually, you have two wait 2 blocks. You can set nb_min_round_confirmations=0 to make it go faster.
|
||||||
roundTxRequiredConfirmations := uint32(0)
|
roundTxRequiredConfirmations := uint32(0)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,8 @@ type Config struct {
|
||||||
ServerAddress string
|
ServerAddress string
|
||||||
EsploraAddress string
|
EsploraAddress string
|
||||||
ServerAccessToken string
|
ServerAccessToken string
|
||||||
|
LogLevel string
|
||||||
|
LogToFile bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBarkService(ctx context.Context, eventPublisher events.EventPublisher, workDir, mnemonic string, config Config) (lnclient.LNClient, error) {
|
func NewBarkService(ctx context.Context, eventPublisher events.EventPublisher, workDir, mnemonic string, config Config) (lnclient.LNClient, error) {
|
||||||
|
|
|
||||||
123
lnclient/bark/logger.go
Normal file
123
lnclient/bark/logger.go
Normal file
|
|
@ -0,0 +1,123 @@
|
||||||
|
//go:build (darwin && (amd64 || arm64)) || (linux && (amd64 || arm64)) || (windows && amd64)
|
||||||
|
|
||||||
|
package bark
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/orandin/lumberjackrus"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
bark "gitlab.com/ark-bitcoin/bark-ffi-bindings/golang/bark"
|
||||||
|
|
||||||
|
"github.com/getAlby/hub/logger"
|
||||||
|
)
|
||||||
|
|
||||||
|
const barkLogFilename = "bark.log"
|
||||||
|
const logDir = "log"
|
||||||
|
|
||||||
|
// setLoggerOnce guards bark.SetLogger, which can only be installed once per
|
||||||
|
// process (calling it again returns an error from the underlying bridge).
|
||||||
|
var setLoggerOnce sync.Once
|
||||||
|
|
||||||
|
// barkLogger forwards bark's internal log records to a dedicated logrus logger
|
||||||
|
// (separate from the main app logger, with its own level and log file) so bark
|
||||||
|
// logs can be tuned independently of the rest of the hub.
|
||||||
|
type barkLogger struct {
|
||||||
|
logger *logrus.Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ bark.BarkLogger = &barkLogger{}
|
||||||
|
|
||||||
|
// Log implements bark.BarkLogger. The record's bark log level is mapped onto the
|
||||||
|
// equivalent logrus level, and the bark target is attached as a structured field.
|
||||||
|
//
|
||||||
|
// IMPORTANT: this must not call back into any bark API that itself emits log
|
||||||
|
// records, or the foreign runtime may stack-overflow or deadlock.
|
||||||
|
func (l *barkLogger) Log(level bark.LogLevel, target string, message string) {
|
||||||
|
l.logger.WithFields(logrus.Fields{
|
||||||
|
"log_type": "bark",
|
||||||
|
"target": target,
|
||||||
|
}).Log(barkLevelToLogrus(level), message)
|
||||||
|
}
|
||||||
|
|
||||||
|
func barkLevelToLogrus(level bark.LogLevel) logrus.Level {
|
||||||
|
switch level {
|
||||||
|
case bark.LogLevelError:
|
||||||
|
return logrus.ErrorLevel
|
||||||
|
case bark.LogLevelWarn:
|
||||||
|
return logrus.WarnLevel
|
||||||
|
case bark.LogLevelInfo:
|
||||||
|
return logrus.InfoLevel
|
||||||
|
case bark.LogLevelDebug:
|
||||||
|
return logrus.DebugLevel
|
||||||
|
case bark.LogLevelTrace:
|
||||||
|
return logrus.TraceLevel
|
||||||
|
}
|
||||||
|
logger.Logger.WithField("log_level", level).Error("Unknown Bark log level")
|
||||||
|
return logrus.ErrorLevel
|
||||||
|
}
|
||||||
|
|
||||||
|
// logrusToBarkLevel maps a logrus level onto the bark log level used to cap
|
||||||
|
// what the FFI bridge emits, so filtered-out records don't cross the boundary.
|
||||||
|
func logrusToBarkLevel(level logrus.Level) bark.LogLevel {
|
||||||
|
switch level {
|
||||||
|
case logrus.PanicLevel, logrus.FatalLevel, logrus.ErrorLevel:
|
||||||
|
return bark.LogLevelError
|
||||||
|
case logrus.WarnLevel:
|
||||||
|
return bark.LogLevelWarn
|
||||||
|
case logrus.InfoLevel:
|
||||||
|
return bark.LogLevelInfo
|
||||||
|
case logrus.DebugLevel:
|
||||||
|
return bark.LogLevelDebug
|
||||||
|
default:
|
||||||
|
return bark.LogLevelTrace
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// installBarkLogger wires bark's internal logs into a dedicated logrus logger.
|
||||||
|
// It is safe to call more than once (e.g. when reopening the wallet); only the
|
||||||
|
// first call installs the logger, as the bridge can only be set once per
|
||||||
|
// process.
|
||||||
|
func installBarkLogger(logLevel logrus.Level, logToFile bool, workDir string) {
|
||||||
|
setLoggerOnce.Do(func() {
|
||||||
|
barkLogrus, err := createBarkLogger(logLevel, logToFile, workDir)
|
||||||
|
if err != nil {
|
||||||
|
logger.Logger.WithError(err).Error("Failed to create Bark logger")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Cap the FFI bridge at the configured level so records below it are
|
||||||
|
// never produced; the dedicated logger applies the same level again.
|
||||||
|
if err := bark.SetLogger(&barkLogger{logger: barkLogrus}, logrusToBarkLevel(logLevel)); err != nil {
|
||||||
|
logger.Logger.WithError(err).Warn("Failed to install Bark logger")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func createBarkLogger(logLevel logrus.Level, logToFile bool, workDir string) (*logrus.Logger, error) {
|
||||||
|
barkLogrus := logrus.New()
|
||||||
|
barkLogrus.SetFormatter(&logrus.JSONFormatter{})
|
||||||
|
barkLogrus.SetOutput(os.Stdout)
|
||||||
|
barkLogrus.SetLevel(logLevel)
|
||||||
|
|
||||||
|
if logToFile {
|
||||||
|
parentDir := filepath.Dir(workDir)
|
||||||
|
barkLogFilePath := filepath.Join(parentDir, logDir, barkLogFilename)
|
||||||
|
barkFileLoggerHook, err := lumberjackrus.NewHook(
|
||||||
|
&lumberjackrus.LogFile{
|
||||||
|
Filename: barkLogFilePath,
|
||||||
|
MaxAge: 3,
|
||||||
|
MaxBackups: 3,
|
||||||
|
},
|
||||||
|
logLevel,
|
||||||
|
&logrus.JSONFormatter{},
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
barkLogrus.AddHook(barkFileLoggerHook)
|
||||||
|
}
|
||||||
|
return barkLogrus, nil
|
||||||
|
}
|
||||||
|
|
@ -384,6 +384,8 @@ func (svc *service) launchLNBackend(ctx context.Context, encryptionKey string) e
|
||||||
ServerAddress: env.BarkServer,
|
ServerAddress: env.BarkServer,
|
||||||
EsploraAddress: env.BarkEsploraServer,
|
EsploraAddress: env.BarkEsploraServer,
|
||||||
ServerAccessToken: env.BarkServerAccessToken,
|
ServerAccessToken: env.BarkServerAccessToken,
|
||||||
|
LogLevel: env.BarkLogLevel,
|
||||||
|
LogToFile: env.LogToFile,
|
||||||
})
|
})
|
||||||
case config.CLNBackendType:
|
case config.CLNBackendType:
|
||||||
CLNAddress, _ := svc.cfg.Get("CLNAddress", encryptionKey)
|
CLNAddress, _ := svc.cfg.Get("CLNAddress", encryptionKey)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue