Start to add zap logger everywhere
This commit is contained in:
@@ -3,7 +3,6 @@ package main
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
@@ -11,13 +10,17 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/debridmediamanager.com/zurg/internal/config"
|
"github.com/debridmediamanager.com/zurg/internal/config"
|
||||||
"github.com/debridmediamanager.com/zurg/internal/mount"
|
|
||||||
"github.com/debridmediamanager.com/zurg/internal/net"
|
"github.com/debridmediamanager.com/zurg/internal/net"
|
||||||
"github.com/debridmediamanager.com/zurg/internal/torrent"
|
"github.com/debridmediamanager.com/zurg/internal/torrent"
|
||||||
|
"github.com/debridmediamanager.com/zurg/internal/zfs"
|
||||||
|
"github.com/debridmediamanager.com/zurg/pkg/logutil"
|
||||||
"github.com/hashicorp/golang-lru/v2/expirable"
|
"github.com/hashicorp/golang-lru/v2/expirable"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
rlog := logutil.NewLogger()
|
||||||
|
log := rlog.Named("main")
|
||||||
|
|
||||||
config, configErr := config.LoadZurgConfig("./config.yml")
|
config, configErr := config.LoadZurgConfig("./config.yml")
|
||||||
if configErr != nil {
|
if configErr != nil {
|
||||||
log.Panicf("Config failed to load: %v", configErr)
|
log.Panicf("Config failed to load: %v", configErr)
|
||||||
@@ -33,29 +36,52 @@ func main() {
|
|||||||
addr := fmt.Sprintf(":%s", config.GetPort())
|
addr := fmt.Sprintf(":%s", config.GetPort())
|
||||||
server := &http.Server{Addr: addr, Handler: mux}
|
server := &http.Server{Addr: addr, Handler: mux}
|
||||||
|
|
||||||
|
mountPoint := config.GetMountPoint()
|
||||||
|
if _, err := os.Stat(mountPoint); os.IsNotExist(err) {
|
||||||
|
if err := os.Mkdir(mountPoint, 0755); err != nil {
|
||||||
|
log.Panicf("Failed to create mount point: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
shutdown := make(chan os.Signal, 1)
|
shutdown := make(chan os.Signal, 1)
|
||||||
signal.Notify(shutdown, os.Interrupt, syscall.SIGTERM)
|
signal.Notify(shutdown, os.Interrupt, syscall.SIGTERM)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
log.Printf("Starting server on %s\n", addr)
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
log.Errorf("Server panic: %v\n", r)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
log.Infof("Starting server on %s\n", addr)
|
||||||
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||||||
log.Panicf("Failed to start server: %v", err)
|
log.Panicf("Failed to start server: %v", err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// Start the mount in a goroutine.
|
// Start the mount in a goroutine with panic recovery.
|
||||||
go func() {
|
go func() {
|
||||||
if err := mount.Mount(config.GetMountPath()); err != nil {
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
log.Errorf("Mount panic: %v\n", r)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
log.Infof("Mounting on %s\n", mountPoint)
|
||||||
|
if err := zfs.Mount(mountPoint); err != nil {
|
||||||
log.Panicf("Failed to mount: %v", err)
|
log.Panicf("Failed to mount: %v", err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
<-shutdown
|
<-shutdown
|
||||||
log.Println("zurg signing off...")
|
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
server.Shutdown(ctx)
|
if err := server.Shutdown(ctx); err != nil {
|
||||||
|
log.Errorf("Server shutdown error: %v\n", err)
|
||||||
|
}
|
||||||
|
if err := zfs.Unmount(mountPoint); err != nil {
|
||||||
|
log.Errorf("Unmount error: %v\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Info("Zurg signing off")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/debridmediamanager.com/zurg/pkg/logutil"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -19,10 +20,14 @@ type ConfigInterface interface {
|
|||||||
MeetsConditions(directory, torrentID, torrentName string, fileNames []string) bool
|
MeetsConditions(directory, torrentID, torrentName string, fileNames []string) bool
|
||||||
GetOnLibraryUpdate() string
|
GetOnLibraryUpdate() string
|
||||||
GetNetworkBufferSize() int
|
GetNetworkBufferSize() int
|
||||||
GetMountPath() string
|
GetMountPoint() string
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadZurgConfig(filename string) (ConfigInterface, error) {
|
func LoadZurgConfig(filename string) (ConfigInterface, error) {
|
||||||
|
rlog := logutil.NewLogger()
|
||||||
|
log := rlog.Named("config")
|
||||||
|
|
||||||
|
log.Debug("Loading config file", filename)
|
||||||
content, err := os.ReadFile(filename)
|
content, err := os.ReadFile(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -35,6 +40,7 @@ func LoadZurgConfig(filename string) (ConfigInterface, error) {
|
|||||||
|
|
||||||
switch initialConfig.Version {
|
switch initialConfig.Version {
|
||||||
case "v1":
|
case "v1":
|
||||||
|
log.Debug("Detected config version: v1")
|
||||||
return loadV1Config(content)
|
return loadV1Config(content)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ type ZurgConfig struct {
|
|||||||
CanRepair bool `yaml:"enable_repair"`
|
CanRepair bool `yaml:"enable_repair"`
|
||||||
OnLibraryUpdate string `yaml:"on_library_update"`
|
OnLibraryUpdate string `yaml:"on_library_update"`
|
||||||
NetworkBufferSize int `yaml:"network_buffer_size"`
|
NetworkBufferSize int `yaml:"network_buffer_size"`
|
||||||
MountPath string `yaml:"mount_path"`
|
MountPoint string `yaml:"mount_point"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (z *ZurgConfig) GetToken() string {
|
func (z *ZurgConfig) GetToken() string {
|
||||||
@@ -57,6 +57,6 @@ func (z *ZurgConfig) GetNetworkBufferSize() int {
|
|||||||
return z.NetworkBufferSize
|
return z.NetworkBufferSize
|
||||||
}
|
}
|
||||||
|
|
||||||
func (z *ZurgConfig) GetMountPath() string {
|
func (z *ZurgConfig) GetMountPoint() string {
|
||||||
return z.MountPath
|
return z.MountPoint
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,14 +5,19 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/debridmediamanager.com/zurg/pkg/logutil"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
func loadV1Config(content []byte) (*ZurgConfigV1, error) {
|
func loadV1Config(content []byte) (*ZurgConfigV1, error) {
|
||||||
|
rlog := logutil.NewLogger()
|
||||||
|
log := rlog.Named("config")
|
||||||
|
|
||||||
var configV1 ZurgConfigV1
|
var configV1 ZurgConfigV1
|
||||||
if err := yaml.Unmarshal(content, &configV1); err != nil {
|
if err := yaml.Unmarshal(content, &configV1); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
log.Debug("V1 config loaded successfully")
|
||||||
|
|
||||||
return &configV1, nil
|
return &configV1, nil
|
||||||
}
|
}
|
||||||
@@ -22,9 +27,13 @@ func (z *ZurgConfigV1) GetVersion() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (z *ZurgConfigV1) GetDirectories() []string {
|
func (z *ZurgConfigV1) GetDirectories() []string {
|
||||||
|
rlog := logutil.NewLogger()
|
||||||
|
log := rlog.Named("config")
|
||||||
|
|
||||||
rootDirectories := make([]string, len(z.Directories))
|
rootDirectories := make([]string, len(z.Directories))
|
||||||
i := 0
|
i := 0
|
||||||
for directory := range z.Directories {
|
for directory := range z.Directories {
|
||||||
|
log.Debug("Adding to rootDirectories", directory)
|
||||||
rootDirectories[i] = directory
|
rootDirectories[i] = directory
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
@@ -32,6 +41,12 @@ func (z *ZurgConfigV1) GetDirectories() []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (z *ZurgConfigV1) GetGroupMap() map[string][]string {
|
func (z *ZurgConfigV1) GetGroupMap() map[string][]string {
|
||||||
|
// Obtain a new sugared logger instance
|
||||||
|
rlog := logutil.NewLogger()
|
||||||
|
log := rlog.Named("config")
|
||||||
|
|
||||||
|
log.Debug("Starting to build the group map from directories")
|
||||||
|
|
||||||
var groupMap = make(map[string][]string)
|
var groupMap = make(map[string][]string)
|
||||||
var groupOrderMap = make(map[string]int) // To store GroupOrder for each directory
|
var groupOrderMap = make(map[string]int) // To store GroupOrder for each directory
|
||||||
|
|
||||||
@@ -39,6 +54,7 @@ func (z *ZurgConfigV1) GetGroupMap() map[string][]string {
|
|||||||
for directory, val := range z.Directories {
|
for directory, val := range z.Directories {
|
||||||
groupMap[val.Group] = append(groupMap[val.Group], directory)
|
groupMap[val.Group] = append(groupMap[val.Group], directory)
|
||||||
groupOrderMap[directory] = val.GroupOrder
|
groupOrderMap[directory] = val.GroupOrder
|
||||||
|
log.Debugf("Added directory to group: %s, group: %s, groupOrder: %d", directory, val.Group, val.GroupOrder)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort the slice based on GroupOrder and then directory name for deterministic order
|
// Sort the slice based on GroupOrder and then directory name for deterministic order
|
||||||
@@ -50,6 +66,7 @@ func (z *ZurgConfigV1) GetGroupMap() map[string][]string {
|
|||||||
return groupOrderMap[dirs[i]] < groupOrderMap[dirs[j]]
|
return groupOrderMap[dirs[i]] < groupOrderMap[dirs[j]]
|
||||||
})
|
})
|
||||||
groupMap[group] = dirs
|
groupMap[group] = dirs
|
||||||
|
log.Debugf("Sorted directories within a group: %s, sortedDirectories: %v", group, dirs)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return a deep copy of the map
|
// Return a deep copy of the map
|
||||||
|
|||||||
@@ -1,38 +0,0 @@
|
|||||||
package mount
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"bazil.org/fuse"
|
|
||||||
"github.com/mdlayher/sdnotify"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Mount(mountpoint string) error {
|
|
||||||
n, err := sdnotify.New()
|
|
||||||
if err != nil && !errors.Is(err, os.ErrNotExist) {
|
|
||||||
log.Fatalf("failed to open systemd notifier: %v", err)
|
|
||||||
}
|
|
||||||
err = n.Notify(
|
|
||||||
sdnotify.Statusf("service started successfully"),
|
|
||||||
sdnotify.Ready,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("failed to send ready notification: %v", err)
|
|
||||||
}
|
|
||||||
return Unmount(mountpoint, n)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Unmount(mountpoint string, n *sdnotify.Notifier) error {
|
|
||||||
log.Println("Unmounting...")
|
|
||||||
err := n.Notify(
|
|
||||||
sdnotify.Statusf("service stopped successfully"),
|
|
||||||
sdnotify.Ready,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("failed to send stop notification: %v", err)
|
|
||||||
}
|
|
||||||
fuse.Unmount(mountpoint)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
21
internal/zfs/fs.go
Normal file
21
internal/zfs/fs.go
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package zfs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"bazil.org/fuse/fs"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FS struct {
|
||||||
|
uid uint32
|
||||||
|
gid uint32
|
||||||
|
umask os.FileMode
|
||||||
|
directIO bool
|
||||||
|
lock sync.RWMutex
|
||||||
|
}
|
||||||
|
|
||||||
|
// Root returns the root path
|
||||||
|
func (f *FS) Root() (fs.Node, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
45
internal/zfs/mount.go
Normal file
45
internal/zfs/mount.go
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
package zfs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"bazil.org/fuse"
|
||||||
|
"bazil.org/fuse/fs"
|
||||||
|
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Mount(mountpoint string) error {
|
||||||
|
options := []fuse.MountOption{
|
||||||
|
fuse.AllowOther(),
|
||||||
|
fuse.AllowNonEmptyMount(),
|
||||||
|
fuse.MaxReadahead(uint32(128 << 10)),
|
||||||
|
fuse.DefaultPermissions(),
|
||||||
|
fuse.FSName("zurgfs"),
|
||||||
|
}
|
||||||
|
c, err := fuse.Mount(mountpoint, options...)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer c.Close()
|
||||||
|
|
||||||
|
srv := fs.New(c, nil)
|
||||||
|
|
||||||
|
filesys := &FS{
|
||||||
|
uid: uint32(unix.Geteuid()),
|
||||||
|
gid: uint32(unix.Getegid()),
|
||||||
|
umask: os.FileMode(0),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Serve our tree via FUSE.
|
||||||
|
if err := srv.Serve(filesys); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Unmount(mountpoint string) error {
|
||||||
|
fuse.Unmount(mountpoint)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
50
internal/zfs/object.go
Normal file
50
internal/zfs/object.go
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
package zfs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"bazil.org/fuse"
|
||||||
|
"bazil.org/fuse/fs"
|
||||||
|
"github.com/debridmediamanager.com/zurg/internal/torrent"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Object struct {
|
||||||
|
fs *FS
|
||||||
|
objectID string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Object) GetObject() (object *torrent.Torrent, err error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Object) Attr(ctx context.Context, attr *fuse.Attr) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Object) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Object) Lookup(ctx context.Context, name string) (fs.Node, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Object) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Object) Open(ctx context.Context, req *fuse.OpenRequest, resp *fuse.OpenResponse) (fs.Handle, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Object) Remove(ctx context.Context, req *fuse.RemoveRequest) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Object) Mkdir(ctx context.Context, req *fuse.MkdirRequest) (fs.Node, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Object) Rename(ctx context.Context, req *fuse.RenameRequest, newDir fs.Node) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
27
pkg/logutil/factory.go
Normal file
27
pkg/logutil/factory.go
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
package logutil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"go.uber.org/zap"
|
||||||
|
"go.uber.org/zap/zapcore"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewLogger() *zap.SugaredLogger {
|
||||||
|
zapConfig := zap.NewDevelopmentConfig()
|
||||||
|
zapConfig.EncoderConfig = zapcore.EncoderConfig{
|
||||||
|
TimeKey: "time",
|
||||||
|
LevelKey: "level",
|
||||||
|
NameKey: "logger",
|
||||||
|
MessageKey: "msg",
|
||||||
|
CallerKey: "",
|
||||||
|
StacktraceKey: "",
|
||||||
|
LineEnding: zapcore.DefaultLineEnding,
|
||||||
|
EncodeLevel: zapcore.CapitalColorLevelEncoder,
|
||||||
|
EncodeTime: zapcore.ISO8601TimeEncoder,
|
||||||
|
EncodeDuration: zapcore.StringDurationEncoder,
|
||||||
|
}
|
||||||
|
logger, _ := zapConfig.Build()
|
||||||
|
defer logger.Sync()
|
||||||
|
sugar := logger.Sugar()
|
||||||
|
|
||||||
|
return sugar
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user