Initial QSfera import

This commit is contained in:
Курнат Андрей
2026-06-07 10:20:04 +03:00
commit 2315f25754
16485 changed files with 4826827 additions and 0 deletions
+58
View File
@@ -0,0 +1,58 @@
// Package log provides debug logging
package log
import (
"encoding/json"
"fmt"
"time"
)
var (
// Default buffer size if any.
DefaultSize = 1024
// DefaultLog logger.
DefaultLog = NewLog()
// Default formatter.
DefaultFormat = TextFormat
)
// Log is debug log interface for reading and writing logs.
type Log interface {
// Read reads log entries from the logger
Read(...ReadOption) ([]Record, error)
// Write writes records to log
Write(Record) error
// Stream log records
Stream() (Stream, error)
}
// Record is log record entry.
type Record struct {
// Timestamp of logged event
Timestamp time.Time `json:"timestamp"`
// Metadata to enrich log record
Metadata map[string]string `json:"metadata"`
// Value contains log entry
Message interface{} `json:"message"`
}
// Stream returns a log stream.
type Stream interface {
Chan() <-chan Record
Stop() error
}
// Format is a function which formats the output.
type FormatFunc func(Record) string
// TextFormat returns text format.
func TextFormat(r Record) string {
t := r.Timestamp.Format("2006-01-02 15:04:05")
return fmt.Sprintf("%s %v", t, r.Message)
}
// JSONFormat is a json Format func.
func JSONFormat(r Record) string {
b, _ := json.Marshal(r)
return string(b)
}
+70
View File
@@ -0,0 +1,70 @@
package log
import "time"
// Option used by the logger.
type Option func(*Options)
// Options are logger options.
type Options struct {
// Format specifies the output format
Format FormatFunc
// Name of the log
Name string
// Size is the size of ring buffer
Size int
}
// Name of the log.
func Name(n string) Option {
return func(o *Options) {
o.Name = n
}
}
// Size sets the size of the ring buffer.
func Size(s int) Option {
return func(o *Options) {
o.Size = s
}
}
func Format(f FormatFunc) Option {
return func(o *Options) {
o.Format = f
}
}
// DefaultOptions returns default options.
func DefaultOptions() Options {
return Options{
Size: DefaultSize,
}
}
// ReadOptions for querying the logs.
type ReadOptions struct {
// Since what time in past to return the logs
Since time.Time
// Count specifies number of logs to return
Count int
// Stream requests continuous log stream
Stream bool
}
// ReadOption used for reading the logs.
type ReadOption func(*ReadOptions)
// Since sets the time since which to return the log records.
func Since(s time.Time) ReadOption {
return func(o *ReadOptions) {
o.Since = s
}
}
// Count sets the number of log records to return.
func Count(c int) ReadOption {
return func(o *ReadOptions) {
o.Count = c
}
}
+81
View File
@@ -0,0 +1,81 @@
package log
import (
"sync"
"github.com/google/uuid"
"go-micro.dev/v4/util/ring"
)
// Should stream from OS.
type osLog struct {
format FormatFunc
buffer *ring.Buffer
subs map[string]*osStream
sync.RWMutex
once sync.Once
}
type osStream struct {
stream chan Record
}
// Read reads log entries from the logger.
func (o *osLog) Read(...ReadOption) ([]Record, error) {
var records []Record
// read the last 100 records
for _, v := range o.buffer.Get(100) {
records = append(records, v.Value.(Record))
}
return records, nil
}
// Write writes records to log.
func (o *osLog) Write(r Record) error {
o.buffer.Put(r)
return nil
}
// Stream log records.
func (o *osLog) Stream() (Stream, error) {
o.Lock()
defer o.Unlock()
// create stream
st := &osStream{
stream: make(chan Record, 128),
}
// save stream
o.subs[uuid.New().String()] = st
return st, nil
}
func (o *osStream) Chan() <-chan Record {
return o.stream
}
func (o *osStream) Stop() error {
return nil
}
func NewLog(opts ...Option) Log {
options := Options{
Format: DefaultFormat,
}
for _, o := range opts {
o(&options)
}
l := &osLog{
format: options.Format,
buffer: ring.New(1024),
subs: make(map[string]*osStream),
}
return l
}