pax_global_header 0000666 0000000 0000000 00000000064 13507015330 0014507 g ustar 00root root 0000000 0000000 52 comment=0387f8acdeb20faf48e539e74906dd633851f3a8
logging-0.2.2/ 0000775 0000000 0000000 00000000000 13507015330 0013136 5 ustar 00root root 0000000 0000000 logging-0.2.2/.github/ 0000775 0000000 0000000 00000000000 13507015330 0014476 5 ustar 00root root 0000000 0000000 logging-0.2.2/.github/assert-contributors.sh 0000664 0000000 0000000 00000001702 13507015330 0021066 0 ustar 00root root 0000000 0000000 #!/usr/bin/env bash
set -e
# Unshallow the repo, this check doesn't work with this enabled
# https://github.com/travis-ci/travis-ci/issues/3412
if [ -f $(git rev-parse --git-dir)/shallow ]; then
git fetch --unshallow || true
fi
SCRIPT_PATH=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )
CONTRIBUTORS=()
EXCLUDED_CONTIBUTORS=('John R. Bradley')
MISSING_CONTIBUTORS=()
shouldBeIncluded () {
for i in "${EXCLUDED_CONTIBUTORS[@]}"
do
if [ "$i" == "$1" ] ; then
return 1
fi
done
return 0
}
IFS=$'\n' #Only split on newline
for contributor in $(git log --format='%aN' | sort -u)
do
if shouldBeIncluded $contributor; then
if ! grep -q "$contributor" "$SCRIPT_PATH/../README.md"; then
MISSING_CONTIBUTORS+=("$contributor")
fi
fi
done
unset IFS
if [ ${#MISSING_CONTIBUTORS[@]} -ne 0 ]; then
echo "Please add the following contributors to the README"
for i in "${MISSING_CONTIBUTORS[@]}"
do
echo "$i"
done
exit 1
fi
logging-0.2.2/.github/lint-commit-message.sh 0000664 0000000 0000000 00000003562 13507015330 0020716 0 ustar 00root root 0000000 0000000 #!/usr/bin/env bash
set -e
display_commit_message_error() {
cat << EndOfMessage
$1
-------------------------------------------------
The preceding commit message is invalid
it failed '$2' of the following checks
* Separate subject from body with a blank line
* Limit the subject line to 50 characters
* Capitalize the subject line
* Do not end the subject line with a period
* Wrap the body at 72 characters
EndOfMessage
exit 1
}
lint_commit_message() {
if [[ "$(echo "$1" | awk 'NR == 2 {print $1;}' | wc -c)" -ne 1 ]]; then
display_commit_message_error "$1" 'Separate subject from body with a blank line'
fi
if [[ "$(echo "$1" | head -n1 | wc -m)" -gt 50 ]]; then
display_commit_message_error "$1" 'Limit the subject line to 50 characters'
fi
if [[ ! $1 =~ ^[A-Z] ]]; then
display_commit_message_error "$1" 'Capitalize the subject line'
fi
if [[ "$(echo "$1" | awk 'NR == 1 {print substr($0,length($0),1)}')" == "." ]]; then
display_commit_message_error "$1" 'Do not end the subject line with a period'
fi
if [[ "$(echo "$1" | awk '{print length}' | sort -nr | head -1)" -gt 72 ]]; then
display_commit_message_error "$1" 'Wrap the body at 72 characters'
fi
}
if [ "$#" -eq 1 ]; then
if [ ! -f "$1" ]; then
echo "$0 was passed one argument, but was not a valid file"
exit 1
fi
lint_commit_message "$(sed -n '/# Please enter the commit message for your changes. Lines starting/q;p' "$1")"
else
# TRAVIS_COMMIT_RANGE is empty for initial branch commit
if [[ "${TRAVIS_COMMIT_RANGE}" != *"..."* ]]; then
parent=$(git log -n 1 --format="%P" ${TRAVIS_COMMIT_RANGE})
TRAVIS_COMMIT_RANGE="${TRAVIS_COMMIT_RANGE}...$parent"
fi
for commit in $(git rev-list ${TRAVIS_COMMIT_RANGE}); do
lint_commit_message "$(git log --format="%B" -n 1 $commit)"
done
fi
logging-0.2.2/.github/lint-disallowed-functions-in-library.sh 0000664 0000000 0000000 00000001116 13507015330 0024200 0 ustar 00root root 0000000 0000000 #!/usr/bin/env bash
set -e
# Disallow usages of functions that cause the program to exit in the library code
SCRIPT_PATH=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )
EXCLUDE_DIRECTORIES="--exclude-dir=examples --exclude-dir=.git --exclude-dir=.github "
DISALLOWED_FUNCTIONS=('os.Exit(' 'panic(' 'Fatal(' 'Fatalf(' 'Fatalln(')
for disallowedFunction in "${DISALLOWED_FUNCTIONS[@]}"
do
if grep -R $EXCLUDE_DIRECTORIES -e "$disallowedFunction" "$SCRIPT_PATH/.." | grep -v -e '_test.go' -e 'nolint'; then
echo "$disallowedFunction may only be used in example code"
exit 1
fi
done
logging-0.2.2/.golangci.yml 0000664 0000000 0000000 00000000275 13507015330 0015526 0 ustar 00root root 0000000 0000000 linters-settings:
govet:
check-shadowing: true
misspell:
locale: US
linters:
enable-all: true
issues:
exclude-use-default: false
max-per-linter: 0
max-same-issues: 50
logging-0.2.2/.travis.yml 0000664 0000000 0000000 00000001141 13507015330 0015244 0 ustar 00root root 0000000 0000000 language: go
go:
- "1.x" # use the latest Go release
env:
- GO111MODULE=on
before_script:
- curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | bash -s -- -b $GOPATH/bin v1.15.0
script:
- golangci-lint run ./...
# - rm -rf examples # Remove examples, no test coverage for them
- go test -coverpkg=$(go list ./... | tr '\n' ',') -coverprofile=cover.out -v -race -covermode=atomic ./...
- bash <(curl -s https://codecov.io/bash)
- bash .github/assert-contributors.sh
- bash .github/lint-disallowed-functions-in-library.sh
- bash .github/lint-commit-message.sh
logging-0.2.2/LICENSE 0000664 0000000 0000000 00000002041 13507015330 0014140 0 ustar 00root root 0000000 0000000 MIT License
Copyright (c) 2018
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.
logging-0.2.2/README.md 0000664 0000000 0000000 00000004750 13507015330 0014423 0 ustar 00root root 0000000 0000000
Pion Logging
The Pion logging library
### Roadmap
The library is used as a part of our WebRTC implementation. Please refer to that [roadmap](https://github.com/pion/webrtc/issues/9) to track our major milestones.
### Community
Pion has an active community on the [Golang Slack](https://invite.slack.golangbridge.org/). Sign up and join the **#pion** channel for discussions and support. You can also use [Pion mailing list](https://groups.google.com/forum/#!forum/pion).
We are always looking to support **your projects**. Please reach out if you have something to build!
If you need commercial support or don't want to use public methods you can contact us at [team@pion.ly](mailto:team@pion.ly)
### Contributing
Check out the **[contributing wiki](https://github.com/pion/webrtc/wiki/Contributing)** to join the group of amazing people making this project possible:
* [John Bradley](https://github.com/kc5nra) - *Original Author*
* [Sean DuBois](https://github.com/Sean-Der) - *Original Author*
* [Michael MacDonald](https://github.com/mjmac) - *Original Author*
* [Woodrow Douglass](https://github.com/wdouglass) - *Test coverage*
* [Michiel De Backker](https://github.com/backkem) - *Docs*
* [Hugo Arregui](https://github.com/hugoArregui) - *Custom Logs*
* [Justin Okamoto](https://github.com/justinokamoto) - *Disabled Logs Update*
### License
MIT License - see [LICENSE](LICENSE) for full text
logging-0.2.2/go.mod 0000664 0000000 0000000 00000000050 13507015330 0014237 0 ustar 00root root 0000000 0000000 module github.com/pion/logging
go 1.12
logging-0.2.2/go.sum 0000664 0000000 0000000 00000000000 13507015330 0014257 0 ustar 00root root 0000000 0000000 logging-0.2.2/logger.go 0000664 0000000 0000000 00000015217 13507015330 0014752 0 ustar 00root root 0000000 0000000 package logging
import (
"fmt"
"io"
"log"
"os"
"strings"
"sync"
)
// Use this abstraction to ensure thread-safe access to the logger's io.Writer
// (which could change at runtime)
type loggerWriter struct {
sync.RWMutex
output io.Writer
}
func (lw *loggerWriter) SetOutput(output io.Writer) {
lw.Lock()
defer lw.Unlock()
lw.output = output
}
func (lw *loggerWriter) Write(data []byte) (int, error) {
lw.RLock()
defer lw.RUnlock()
return lw.output.Write(data)
}
// DefaultLeveledLogger encapsulates functionality for providing logging at
// user-defined levels
type DefaultLeveledLogger struct {
level LogLevel
writer *loggerWriter
trace *log.Logger
debug *log.Logger
info *log.Logger
warn *log.Logger
err *log.Logger
}
// WithTraceLogger is a chainable configuration function which sets the
// Trace-level logger
func (ll *DefaultLeveledLogger) WithTraceLogger(log *log.Logger) *DefaultLeveledLogger {
ll.trace = log
return ll
}
// WithDebugLogger is a chainable configuration function which sets the
// Debug-level logger
func (ll *DefaultLeveledLogger) WithDebugLogger(log *log.Logger) *DefaultLeveledLogger {
ll.debug = log
return ll
}
// WithInfoLogger is a chainable configuration function which sets the
// Info-level logger
func (ll *DefaultLeveledLogger) WithInfoLogger(log *log.Logger) *DefaultLeveledLogger {
ll.info = log
return ll
}
// WithWarnLogger is a chainable configuration function which sets the
// Warn-level logger
func (ll *DefaultLeveledLogger) WithWarnLogger(log *log.Logger) *DefaultLeveledLogger {
ll.warn = log
return ll
}
// WithErrorLogger is a chainable configuration function which sets the
// Error-level logger
func (ll *DefaultLeveledLogger) WithErrorLogger(log *log.Logger) *DefaultLeveledLogger {
ll.err = log
return ll
}
// WithOutput is a chainable configuration function which sets the logger's
// logging output to the supplied io.Writer
func (ll *DefaultLeveledLogger) WithOutput(output io.Writer) *DefaultLeveledLogger {
ll.writer.SetOutput(output)
return ll
}
func (ll *DefaultLeveledLogger) logf(logger *log.Logger, level LogLevel, format string, args ...interface{}) {
if ll.level.Get() < level {
return
}
callDepth := 3 // this frame + wrapper func + caller
msg := fmt.Sprintf(format, args...)
if err := logger.Output(callDepth, msg); err != nil {
fmt.Fprintf(os.Stderr, "Unable to log: %s", err)
}
}
// SetLevel sets the logger's logging level
func (ll *DefaultLeveledLogger) SetLevel(newLevel LogLevel) {
ll.level.Set(newLevel)
}
// Trace emits the preformatted message if the logger is at or below LogLevelTrace
func (ll *DefaultLeveledLogger) Trace(msg string) {
ll.logf(ll.trace, LogLevelTrace, msg)
}
// Tracef formats and emits a message if the logger is at or below LogLevelTrace
func (ll *DefaultLeveledLogger) Tracef(format string, args ...interface{}) {
ll.logf(ll.trace, LogLevelTrace, format, args...)
}
// Debug emits the preformatted message if the logger is at or below LogLevelDebug
func (ll *DefaultLeveledLogger) Debug(msg string) {
ll.logf(ll.debug, LogLevelDebug, msg)
}
// Debugf formats and emits a message if the logger is at or below LogLevelDebug
func (ll *DefaultLeveledLogger) Debugf(format string, args ...interface{}) {
ll.logf(ll.debug, LogLevelDebug, format, args...)
}
// Info emits the preformatted message if the logger is at or below LogLevelInfo
func (ll *DefaultLeveledLogger) Info(msg string) {
ll.logf(ll.info, LogLevelInfo, msg)
}
// Infof formats and emits a message if the logger is at or below LogLevelInfo
func (ll *DefaultLeveledLogger) Infof(format string, args ...interface{}) {
ll.logf(ll.info, LogLevelInfo, format, args...)
}
// Warn emits the preformatted message if the logger is at or below LogLevelWarn
func (ll *DefaultLeveledLogger) Warn(msg string) {
ll.logf(ll.warn, LogLevelWarn, msg)
}
// Warnf formats and emits a message if the logger is at or below LogLevelWarn
func (ll *DefaultLeveledLogger) Warnf(format string, args ...interface{}) {
ll.logf(ll.warn, LogLevelWarn, format, args...)
}
// Error emits the preformatted message if the logger is at or below LogLevelError
func (ll *DefaultLeveledLogger) Error(msg string) {
ll.logf(ll.err, LogLevelError, msg)
}
// Errorf formats and emits a message if the logger is at or below LogLevelError
func (ll *DefaultLeveledLogger) Errorf(format string, args ...interface{}) {
ll.logf(ll.err, LogLevelError, format, args...)
}
// NewDefaultLeveledLoggerForScope returns a configured LeveledLogger
func NewDefaultLeveledLoggerForScope(scope string, level LogLevel, writer io.Writer) *DefaultLeveledLogger {
if writer == nil {
writer = os.Stdout
}
logger := &DefaultLeveledLogger{
writer: &loggerWriter{output: writer},
level: level,
}
return logger.
WithTraceLogger(log.New(logger.writer, fmt.Sprintf("%s TRACE: ", scope), log.Lmicroseconds|log.Lshortfile)).
WithDebugLogger(log.New(logger.writer, fmt.Sprintf("%s DEBUG: ", scope), log.Lmicroseconds|log.Lshortfile)).
WithInfoLogger(log.New(logger.writer, fmt.Sprintf("%s INFO: ", scope), log.LstdFlags)).
WithWarnLogger(log.New(logger.writer, fmt.Sprintf("%s WARNING: ", scope), log.LstdFlags)).
WithErrorLogger(log.New(logger.writer, fmt.Sprintf("%s ERROR: ", scope), log.LstdFlags))
}
// DefaultLoggerFactory define levels by scopes and creates new DefaultLeveledLogger
type DefaultLoggerFactory struct {
Writer io.Writer
DefaultLogLevel LogLevel
ScopeLevels map[string]LogLevel
}
// NewDefaultLoggerFactory creates a new DefaultLoggerFactory
func NewDefaultLoggerFactory() *DefaultLoggerFactory {
factory := DefaultLoggerFactory{}
factory.DefaultLogLevel = LogLevelError
factory.ScopeLevels = make(map[string]LogLevel)
factory.Writer = os.Stdout
logLevels := map[string]LogLevel{
"DISABLE": LogLevelDisabled,
"ERROR": LogLevelError,
"WARN": LogLevelWarn,
"INFO": LogLevelInfo,
"DEBUG": LogLevelDebug,
"TRACE": LogLevelTrace,
}
for name, level := range logLevels {
env := os.Getenv(fmt.Sprintf("PION_LOG_%s", name))
if env == "" {
env = os.Getenv(fmt.Sprintf("PIONS_LOG_%s", name))
}
if env == "" {
continue
}
if strings.ToLower(env) == "all" {
factory.DefaultLogLevel = level
continue
}
scopes := strings.Split(strings.ToLower(env), ",")
for _, scope := range scopes {
factory.ScopeLevels[scope] = level
}
}
return &factory
}
// NewLogger returns a configured LeveledLogger for the given , argsscope
func (f *DefaultLoggerFactory) NewLogger(scope string) LeveledLogger {
logLevel := f.DefaultLogLevel
if f.ScopeLevels != nil {
scopeLevel, found := f.ScopeLevels[scope]
if found {
logLevel = scopeLevel
}
}
return NewDefaultLeveledLoggerForScope(scope, logLevel, f.Writer)
}
logging-0.2.2/logging_test.go 0000664 0000000 0000000 00000005623 13507015330 0016160 0 ustar 00root root 0000000 0000000 package logging_test
import (
"bytes"
"os"
"strings"
"testing"
"github.com/pion/logging"
)
func testNoDebugLevel(t *testing.T, logger *logging.DefaultLeveledLogger) {
var outBuf bytes.Buffer
logger.WithOutput(&outBuf)
logger.Debug("this shouldn't be logged")
if outBuf.Len() > 0 {
t.Error("Debug was logged when it shouldn't have been")
}
logger.Debugf("this shouldn't be logged")
if outBuf.Len() > 0 {
t.Error("Debug was logged when it shouldn't have been")
}
}
func testDebugLevel(t *testing.T, logger *logging.DefaultLeveledLogger) {
var outBuf bytes.Buffer
logger.WithOutput(&outBuf)
dbgMsg := "this is a debug message"
logger.Debug(dbgMsg)
if !strings.Contains(outBuf.String(), dbgMsg) {
t.Errorf("Expected to find %q in %q, but didn't", dbgMsg, outBuf.String())
}
logger.Debugf(dbgMsg)
if !strings.Contains(outBuf.String(), dbgMsg) {
t.Errorf("Expected to find %q in %q, but didn't", dbgMsg, outBuf.String())
}
}
func testWarnLevel(t *testing.T, logger *logging.DefaultLeveledLogger) {
var outBuf bytes.Buffer
logger.WithOutput(&outBuf)
warnMsg := "this is a warning message"
logger.Warn(warnMsg)
if !strings.Contains(outBuf.String(), warnMsg) {
t.Errorf("Expected to find %q in %q, but didn't", warnMsg, outBuf.String())
}
logger.Warnf(warnMsg)
if !strings.Contains(outBuf.String(), warnMsg) {
t.Errorf("Expected to find %q in %q, but didn't", warnMsg, outBuf.String())
}
}
func testErrorLevel(t *testing.T, logger *logging.DefaultLeveledLogger) {
var outBuf bytes.Buffer
logger.WithOutput(&outBuf)
errMsg := "this is an error message"
logger.Error(errMsg)
if !strings.Contains(outBuf.String(), errMsg) {
t.Errorf("Expected to find %q in %q, but didn't", errMsg, outBuf.String())
}
logger.Errorf(errMsg)
if !strings.Contains(outBuf.String(), errMsg) {
t.Errorf("Expected to find %q in %q, but didn't", errMsg, outBuf.String())
}
}
func TestDefaultLoggerFactory(t *testing.T) {
f := logging.DefaultLoggerFactory{
Writer: os.Stdout,
DefaultLogLevel: logging.LogLevelWarn,
ScopeLevels: map[string]logging.LogLevel{
"foo": logging.LogLevelDebug,
},
}
logger := f.NewLogger("baz")
bazLogger, ok := logger.(*logging.DefaultLeveledLogger)
if !ok {
t.Error("Invalid logger type")
}
testNoDebugLevel(t, bazLogger)
testWarnLevel(t, bazLogger)
logger = f.NewLogger("foo")
fooLogger, ok := logger.(*logging.DefaultLeveledLogger)
if !ok {
t.Error("Invalid logger type")
}
testDebugLevel(t, fooLogger)
}
func TestDefaultLogger(t *testing.T) {
logger := logging.
NewDefaultLeveledLoggerForScope("test1", logging.LogLevelWarn, os.Stdout)
testNoDebugLevel(t, logger)
testWarnLevel(t, logger)
testErrorLevel(t, logger)
}
func TestSetLevel(t *testing.T) {
logger := logging.
NewDefaultLeveledLoggerForScope("testSetLevel", logging.LogLevelWarn, os.Stdout)
testNoDebugLevel(t, logger)
logger.SetLevel(logging.LogLevelDebug)
testDebugLevel(t, logger)
}
logging-0.2.2/scoped.go 0000664 0000000 0000000 00000003570 13507015330 0014747 0 ustar 00root root 0000000 0000000 package logging
import (
"sync/atomic"
)
// LogLevel represents the level at which the logger will emit log messages
type LogLevel int32
// Set updates the LogLevel to the supplied value
func (ll *LogLevel) Set(newLevel LogLevel) {
atomic.StoreInt32((*int32)(ll), int32(newLevel))
}
// Get retrieves the current LogLevel value
func (ll *LogLevel) Get() LogLevel {
return LogLevel(atomic.LoadInt32((*int32)(ll)))
}
func (ll LogLevel) String() string {
switch ll {
case LogLevelDisabled:
return "Disabled"
case LogLevelError:
return "Error"
case LogLevelWarn:
return "Warn"
case LogLevelInfo:
return "Info"
case LogLevelDebug:
return "Debug"
case LogLevelTrace:
return "Trace"
default:
return "UNKNOWN"
}
}
const (
// LogLevelDisabled completely disables logging of any events
LogLevelDisabled LogLevel = iota
// LogLevelError is for fatal errors which should be handled by user code,
// but are logged to ensure that they are seen
LogLevelError
// LogLevelWarn is for logging abnormal, but non-fatal library operation
LogLevelWarn
// LogLevelInfo is for logging normal library operation (e.g. state transitions, etc.)
LogLevelInfo
// LogLevelDebug is for logging low-level library information (e.g. internal operations)
LogLevelDebug
// LogLevelTrace is for logging very low-level library information (e.g. network traces)
LogLevelTrace
)
// LeveledLogger is the basic pion Logger interface
type LeveledLogger interface {
Trace(msg string)
Tracef(format string, args ...interface{})
Debug(msg string)
Debugf(format string, args ...interface{})
Info(msg string)
Infof(format string, args ...interface{})
Warn(msg string)
Warnf(format string, args ...interface{})
Error(msg string)
Errorf(format string, args ...interface{})
}
// LoggerFactory is the basic pion LoggerFactory interface
type LoggerFactory interface {
NewLogger(scope string) LeveledLogger
}