mirror of
https://github.com/siderolabs/talos.git
synced 2025-09-14 18:31:10 +02:00
Add JSON over TCP support. Add support for multiple loggers. Make logging configurable. Signed-off-by: Alexey Palazhchenko <alexey.palazhchenko@talos-systems.com>
105 lines
2.4 KiB
Go
105 lines
2.4 KiB
Go
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
package logging
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/talos-systems/talos/internal/app/machined/pkg/runtime"
|
|
"github.com/talos-systems/talos/pkg/follow"
|
|
"github.com/talos-systems/talos/pkg/tail"
|
|
)
|
|
|
|
// FileLoggingManager implements simple logging to files.
|
|
type FileLoggingManager struct {
|
|
logDirectory string
|
|
}
|
|
|
|
// NewFileLoggingManager initializes new FileLoggingManager.
|
|
func NewFileLoggingManager(logDirectory string) *FileLoggingManager {
|
|
return &FileLoggingManager{
|
|
logDirectory: logDirectory,
|
|
}
|
|
}
|
|
|
|
// ServiceLog implements runtime.LoggingManager interface.
|
|
func (manager *FileLoggingManager) ServiceLog(id string) runtime.LogHandler {
|
|
return &fileLogHandler{
|
|
logDirectory: manager.logDirectory,
|
|
id: id,
|
|
}
|
|
}
|
|
|
|
// SetSenders implements runtime.LoggingManager interface (by doing nothing).
|
|
func (manager *FileLoggingManager) SetSenders([]runtime.LogSender) []runtime.LogSender {
|
|
return nil
|
|
}
|
|
|
|
type fileLogHandler struct {
|
|
path string
|
|
|
|
logDirectory string
|
|
id string
|
|
}
|
|
|
|
func (handler *fileLogHandler) buildPath() error {
|
|
if strings.ContainsAny(handler.id, string(os.PathSeparator)+".") {
|
|
return fmt.Errorf("service ID is invalid")
|
|
}
|
|
|
|
handler.path = filepath.Join(handler.logDirectory, handler.id+".log")
|
|
|
|
return nil
|
|
}
|
|
|
|
// Writer implements runtime.LogHandler interface.
|
|
func (handler *fileLogHandler) Writer() (io.WriteCloser, error) {
|
|
if err := handler.buildPath(); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return os.OpenFile(handler.path, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0o666)
|
|
}
|
|
|
|
// Reader implements runtime.LogHandler interface.
|
|
func (handler *fileLogHandler) Reader(opts ...runtime.LogOption) (io.ReadCloser, error) {
|
|
var opt runtime.LogOptions
|
|
|
|
for _, o := range opts {
|
|
if err := o(&opt); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
if err := handler.buildPath(); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
f, err := os.OpenFile(handler.path, os.O_RDONLY, 0)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if opt.TailLines != nil {
|
|
err = tail.SeekLines(f, *opt.TailLines)
|
|
if err != nil {
|
|
f.Close() //nolint:errcheck
|
|
|
|
return nil, fmt.Errorf("error tailing log: %w", err)
|
|
}
|
|
}
|
|
|
|
if opt.Follow {
|
|
return follow.NewReader(context.Background(), f), nil
|
|
}
|
|
|
|
return f, nil
|
|
}
|