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
+81
View File
@@ -0,0 +1,81 @@
# Created by https://www.gitignore.io/api/vim,macOS,IntelliJ+allb,go
# Edit at https://www.gitignore.io/?templates=vim,macOS,IntelliJ+allb,go
### Go ###
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
# Test binary, built with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Dependency directories (remove the comment below to include it)
# vendor/
### Go Patch ###
/vendor/
/Godeps/
#!! ERROR: intellij+allb is undefined. Use list command to see defined gitignore types !!#
### macOS ###
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### Vim ###
# Swap
[._]*.s[a-v][a-z]
[._]*.sw[a-p]
[._]s[a-rt-v][a-z]
[._]ss[a-gi-z]
[._]sw[a-p]
# Session
Session.vim
Sessionx.vim
# Temporary
.netrwhist
*~
# Auto-generated tag files
tags
# Persistent undo
[._]*.un~
# Coc configuration directory
.vim
# End of https://www.gitignore.io/api/vim,macOS,IntelliJ+allb,go
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 Simon Sawert
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+34
View File
@@ -0,0 +1,34 @@
# Logrusr
[![GitHub Actions](https://github.com/bombsimon/logrusr/actions/workflows/go.yml/badge.svg)](https://github.com/bombsimon/logrusr/actions/workflows/go.yml)
[![Coverage Status](https://coveralls.io/repos/github/bombsimon/logrusr/badge.svg?branch=main)](https://coveralls.io/github/bombsimon/logrusr?branch=main)
[![Go Report Card](https://goreportcard.com/badge/github.com/bombsimon/logrusr)](https://goreportcard.com/report/github.com/bombsimon/logrusr)
A [logr](https://github.com/go-logr/logr) implementation using
[logrus](https://github.com/sirupsen/logrus).
## Usage
```go
import (
"github.com/bombsimon/logrusr/v3"
"github.com/go-logr/logr"
"github.com/sirupsen/logrus"
)
func main() {
logrusLog := logrus.New()
log := logrusr.New(logrusLog)
log = log.WithName("MyName").WithValues("user", "you")
log.Info("Logr in action!", "the answer", 42)
}
```
For more details, see [example](example/main.go).
## Implementation details
The New method takes a `logrus.FieldLogger` interface as input which means
this works with both `logrus.Logger` and `logrus.Entry`. This is currently a
quite naive implementation in early state. Use with caution.
+237
View File
@@ -0,0 +1,237 @@
package logrusr
import (
"encoding/json"
"fmt"
"path/filepath"
"runtime"
"strings"
"github.com/go-logr/logr"
"github.com/sirupsen/logrus"
)
// According to the specification of the Logger interface calling the InfoLogger
// directly on the logger should be the same as calling them on V(0). Since
// logrus level 0 is PanicLevel and Infolevel doesn't start until V(4) we use
// this constant to be able to calculate what V(n) values should mean.
const logrusDiffToInfo = 4
// FormatFunc is the function to format log values with for non primitive data.
// By default, this is empty and the data will be JSON marshaled.
type FormatFunc func(interface{}) string
// Option is options to give when construction a logrusr logger.
type Option func(l *logrusr)
// WithFormatter will set the FormatFunc to use.
func WithFormatter(f FormatFunc) Option {
return func(l *logrusr) {
l.defaultFormatter = f
}
}
// WithReportCaller will enable reporting of the caller.
func WithReportCaller() Option {
return func(l *logrusr) {
l.reportCaller = true
}
}
// WithName will set an initial name instead of having to call `WithName` on the
// logger itself after constructing it.
func WithName(name ...string) Option {
return func(l *logrusr) {
l.name = name
l.logger = l.logger.WithField(
"logger", strings.Join(l.name, "."),
)
}
}
type logrusr struct {
name []string
depth int
reportCaller bool
logger *logrus.Entry
defaultFormatter FormatFunc
}
// New will return a new logr.Logger created from a logrus.FieldLogger.
func New(l logrus.FieldLogger, opts ...Option) logr.Logger {
// Immediately convert the FieldLogger to an Entry so we don't have to type
// cast and can use methods that exist on the Entry but not the FieldLogger
// interface.
logger := &logrusr{
depth: 0,
logger: l.WithFields(logrus.Fields{}),
}
for _, o := range opts {
o(logger)
}
return logr.New(logger)
}
// Init receives optional information about the library.
func (l *logrusr) Init(ri logr.RuntimeInfo) {
// By default `CallDepth` is set to 1 which means one of the frames is
// skipped by default. This was originally missed in this library making the
// default behavior and `WithCallDepth(0)` behave differently.
// To be backwards compatible without affecting anyone manually setting the
// call depth we reduce 1 from the default depth instead of not adding it.
// See https://github.com/bombsimon/logrusr/issues/19 for more info.
l.depth = ri.CallDepth - 1
}
// Enabled tests whether this Logger is enabled. It will return true if the
// logrus.Logger has a level set to logrus.InfoLevel or higher (Warn/Panic).
// According to the documentation, level V(0) should be equivalent as calling
// Info() directly on the logger. To ensure this the constant `logrusDiffToInfo`
// will be added to all passed values so that V(0) creates a logger with level
// logrus.InfoLevel and V(2) would create a logger with level logrus.TraceLevel.
// This menas that if logrus is set to logrus.InfoLevel or **higher** this
// method will return true, otherwise false.
func (l *logrusr) Enabled(level int) bool {
// logrus.InfoLevel has value 4 so if the level on the logger is set to 0 we
// should only be seen as enabled if the logrus logger has a severity of
// info or higher.
return l.logger.Logger.IsLevelEnabled(logrus.Level(level + logrusDiffToInfo))
}
// Info logs info messages if the logger is enabled, that is if the level on the
// logger is set to logrus.InfoLevel or less.
func (l *logrusr) Info(level int, msg string, keysAndValues ...interface{}) {
log := l.logger
if c := l.caller(); c != "" {
log = log.WithField("caller", c)
}
log.
WithFields(listToLogrusFields(l.defaultFormatter, keysAndValues...)).
Log(logrus.Level(level+logrusDiffToInfo), msg)
}
// Error logs error messages. Since the log will be written with `Error` level
// it won't show if the severity of the underlying logrus logger is less than
// Error.
func (l *logrusr) Error(err error, msg string, keysAndValues ...interface{}) {
log := l.logger
if c := l.caller(); c != "" {
log = log.WithField("caller", c)
}
log.
WithFields(listToLogrusFields(l.defaultFormatter, keysAndValues...)).
WithError(err).
Error(msg)
}
// WithValues returns a new logger with additional key/values pairs. This is
// equivalent to logrus WithFields() but takes a list of even arguments
// (key/value pairs) instead of a map as input. If an odd number of arguments
// are sent all values will be discarded.
func (l *logrusr) WithValues(keysAndValues ...interface{}) logr.LogSink {
newLogger := l.copyLogger()
newLogger.logger = newLogger.logger.WithFields(
listToLogrusFields(l.defaultFormatter, keysAndValues...),
)
return newLogger
}
// WithName is a part of the Logger interface. This will set the key "logger" as
// a logrus field to identify the instance.
func (l *logrusr) WithName(name string) logr.LogSink {
newLogger := l.copyLogger()
newLogger.name = append(newLogger.name, name)
newLogger.logger = newLogger.logger.WithField(
"logger", strings.Join(newLogger.name, "."),
)
return newLogger
}
// listToLogrusFields converts a list of arbitrary length to key/value paris.
func listToLogrusFields(formatter func(interface{}) string, keysAndValues ...interface{}) logrus.Fields {
f := make(logrus.Fields)
// Skip all fields if it's not an even length list.
if len(keysAndValues)%2 != 0 {
return f
}
for i := 0; i < len(keysAndValues); i += 2 {
k, v := keysAndValues[i], keysAndValues[i+1]
if s, ok := k.(string); ok {
// Try to avoid marshaling known types.
switch vVal := v.(type) {
case int, int8, int16, int32, int64,
uint, uint8, uint16, uint32, uint64,
float32, float64, complex64, complex128,
string, bool:
f[s] = vVal
case []byte:
f[s] = string(vVal)
default:
if formatter != nil {
f[s] = formatter(v)
} else {
j, _ := json.Marshal(vVal)
f[s] = string(j)
}
}
}
}
return f
}
// copyLogger copies the logger creating a new slice of the name but preserving
// the formatter and actual logrus logger.
func (l *logrusr) copyLogger() *logrusr {
newLogger := &logrusr{
name: make([]string, len(l.name)),
depth: l.depth,
reportCaller: l.reportCaller,
logger: l.logger.Dup(),
defaultFormatter: l.defaultFormatter,
}
copy(newLogger.name, l.name)
return newLogger
}
// WithCallDepth implements the optional WithCallDepth to offset the call stack
// when reporting caller.
func (l *logrusr) WithCallDepth(depth int) logr.LogSink {
newLogger := l.copyLogger()
newLogger.depth = depth
return newLogger
}
// caller will return the caller of the logging method.
func (l *logrusr) caller() string {
// Check if we should even report the caller.
if !l.reportCaller {
return ""
}
// +1 for this frame.
// +1 for frame calling here (Info/Error)
// +1 for logr frame
_, file, line, ok := runtime.Caller(l.depth + 3)
if !ok {
return ""
}
return fmt.Sprintf("%s:%d", filepath.Base(file), line)
}