Latest commit

History

212 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

go-logging

Build StatusLicenseGoDocGo Report Card

go-logging is a high-performance logging library for golang.

  • Simple: It supports only necessary operations and easy to get started.
  • Fast: Asynchronous logging without runtime-related fields has an extremely low delay of about 800 nano-seconds.
  • Performance in my laptop as follow.
BenchmarkSync 300000 4018 ns/op
BenchmarkAsync 300000 4229 ns/op
BenchmarkBasicSync 500000 2504 ns/op
BenchmarkBasicAsync 1000000 2495 ns/op
BenchmarkPrintln 1000000 1550 ns/op

Getting Started

Installation

The step below will download the library source code to ${GOPATH}/src/github.com/ccding/go-logging.

go get github.com/ccding/go-logging/logging

Given the source code downloaded, it makes you be able to run the examples, tests, and benchmarks.

cd${GOPATH}/src/github.com/ccding/go-logging/logging
go get
go run ../example.go
go test -v -bench .

Example

go-logging is used like any other Go libraries. You can simply use the library in this way.

import"github.com/ccding/go-logging/logging"

Here is a simple example.

package main
import (
"github.com/ccding/go-logging/logging"
)
funcmain() {
logger, _:=logging.SimpleLogger("main")
logger.Error("this is a test from error")
logger.Destroy()
}

Configuration

Construction Functions

It has the following functions to create a logger.

// with BasicFormat and writing to stdoutSimpleLogger(namestring) (*Logger, error)
// with BasicFormat and writing to DefaultFileNameBasicLogger(namestring) (*Logger, error)
// with RichFormatand writing to DefaultFileNameRichLogger(namestring) (*Logger, error)
// with detailed configuration and writing to fileFileLogger(namestring, levelLevel, formatstring, timeFormatstring, filestring, syncbool) (*Logger, error)
// with detailed configuration and writing to a writerWriterLogger(namestring, levelLevel, formatstring, timeFormatstring, outio.Writer, syncbool) (*Logger, error)
// read configurations from a config fileConfigLogger(filenamestring) (*Logger, error)

The meanings of these fields are

namestring// logger namelevelLevel// record level higher than this will be printedformatstring// format configurationtimeFormatstring// format for timefilestring// file name for loggingoutio.Writer// writer for loggingsyncbool// use sync or async way to record logs

The detailed description of these fields will be presented later.

Logging Functions

It supports the following functions for logging. All of these functions are thread-safe.

(*Logger) Logf(levelLevel, formatstring, v...interface{})
(*Logger) Log(levelLevel, v...interface{})
(*Logger) Criticalf(formatstring, v...interface{})
(*Logger) Critical(v...interface{})
(*Logger) Fatalf(formatstring, v...interface{})
(*Logger) Fatal(v...interface{})
(*Logger) Errorf(formatstring, v...interface{})
(*Logger) Error(v...interface{})
(*Logger) Warningf(formatstring, v...interface{})
(*Logger) Warning(v...interface{})
(*Logger) Warnf(formatstring, v...interface{})
(*Logger) Warn(v...interface{})
(*Logger) Infof(formatstring, v...interface{})
(*Logger) Info(v...interface{})
(*Logger) Debugf(formatstring, v...interface{})
(*Logger) Debug(v...interface{})
(*Logger) Notsetf(formatstring, v...interface{})
(*Logger) Notset(v...interface{})

Logger Operations

The logger supports the following operations. In these functions, SetWriter and Destroy are not thread-safe, while others are. All these functions are running in a synchronous way.

// Getter functions
(*Logger) Name() string// get name
(*Logger) TimeFormat() string// get time format
(*Logger) Level() Level// get level [this function is thread safe]
(*Logger) RecordFormat() string// get the first part of the format
(*Logger) RecordArgs() []string// get the second part of the format
(*Logger) Writer() io.Writer// get writer
(*Logger) Sync() bool// get sync or async// Setter functions
(*Logger) SetLevel(levelLevel) // set level [this function is thread safe]
(*Logger) SetWriter(out...io.Writer) // set multiple writers// Other functions
(*Logger) Flush() // flush the writer
(*Logger) Destroy() // destroy the logger

Fields Description

Name

Name field is a string, which can be written to the logging and used to separate multiple loggers. It allows two logger having the same name. There is not any default value for name.

Logging Levels

There are these levels in logging.

CRITICAL50FATALCRITICALERROR40WARNING30WARNWARNINGINFO20DEBUG10NOTSET0
Record Format

The record format is described by a string, which has two parts separated by \n. The first part describes the format of the log, and the second part lists all the fields to be shown in the log. In other word, the first part is the first parameter format of fmt.Printf(format string, v ...interface{}), and the second part describes the second parameter v of it. It is not allowed to have \n in the first part. The fields in the second part are separated by comma ,, while extra blank spaces are allowed. An example of the format string is

constBasicFormat="%s [%6s] %30s - %s\n name,levelname,time,message"

which is the pre-defined BasicFormat used by BasicLogger() and SimpleLogger().

It supports the following fields for the second part of the format.

"name"string%s// name of the logger"seqid"uint64%d// sequence number"levelno"int32%d// level number"levelname"string%s// level name"created"int64%d// starting time of the logger"nsecs"int64%d// nanosecond of the starting time"time"string%s// record created time"timestamp"int64%d// timestamp of record"rtime"int64%d// relative time since started"filename"string%s// source filename of the caller"pathname"string%s// filename with path"module"string%s// executable filename"lineno"int%d// line number in source code"funcname"string%s// function name of the caller"process"int%d// process id"message"string%s// logger message

The following runtime-related fields is extremely expensive and slow, please be careful when using them.

"filename"string%s// source filename of the caller"pathname"string%s// filename with path"lineno"int%d// line number in source code"funcname"string%s// function name of the caller

There are a few pre-defined values for record format.

BasicFormat="%s [%6s] %30s - %s\n name,levelname,time,message"RichFormat="%s [%6s] %d %30s - %d - %s:%s:%d - %s\n name, levelname, seqid, time, filename, funcname, lineno, message"
Time Format

We use the same time format as golang. The default time format is

DefaultTimeFormat="2006-01-02 15:04:05.999999999"// default time format
File Name, Writer, and Sync

The meaning of these fields are obvious. Filename is used to create writer. We also allow the user create a writer by herself and pass it to the logger. Sync describes whether the user would like to use synchronous or asynchronous method to write logs. true value means synchronous method, and false value means asynchronous way. We suggest you use asynchronous way because it causes extremely low extra delay by the logging functions.

Contributors

In alphabetical order

About

the logging package for golang

Resources

Stars

66 stars

Watchers

4 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Latest commit

History

212 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

go-logging

Build StatusLicenseGoDocGo Report Card

go-logging is a high-performance logging library for golang.

  • Simple: It supports only necessary operations and easy to get started.
  • Fast: Asynchronous logging without runtime-related fields has an extremely low delay of about 800 nano-seconds.
  • Performance in my laptop as follow.
BenchmarkSync 300000 4018 ns/op
BenchmarkAsync 300000 4229 ns/op
BenchmarkBasicSync 500000 2504 ns/op
BenchmarkBasicAsync 1000000 2495 ns/op
BenchmarkPrintln 1000000 1550 ns/op

Getting Started

Installation

The step below will download the library source code to ${GOPATH}/src/github.com/ccding/go-logging.

go get github.com/ccding/go-logging/logging

Given the source code downloaded, it makes you be able to run the examples, tests, and benchmarks.

cd${GOPATH}/src/github.com/ccding/go-logging/logging
go get
go run ../example.go
go test -v -bench .

Example

go-logging is used like any other Go libraries. You can simply use the library in this way.

import"github.com/ccding/go-logging/logging"

Here is a simple example.

package main
import (
"github.com/ccding/go-logging/logging"
)
funcmain() {
logger, _:=logging.SimpleLogger("main")
logger.Error("this is a test from error")
logger.Destroy()
}

Configuration

Construction Functions

It has the following functions to create a logger.

// with BasicFormat and writing to stdoutSimpleLogger(namestring) (*Logger, error)
// with BasicFormat and writing to DefaultFileNameBasicLogger(namestring) (*Logger, error)
// with RichFormatand writing to DefaultFileNameRichLogger(namestring) (*Logger, error)
// with detailed configuration and writing to fileFileLogger(namestring, levelLevel, formatstring, timeFormatstring, filestring, syncbool) (*Logger, error)
// with detailed configuration and writing to a writerWriterLogger(namestring, levelLevel, formatstring, timeFormatstring, outio.Writer, syncbool) (*Logger, error)
// read configurations from a config fileConfigLogger(filenamestring) (*Logger, error)

The meanings of these fields are

namestring// logger namelevelLevel// record level higher than this will be printedformatstring// format configurationtimeFormatstring// format for timefilestring// file name for loggingoutio.Writer// writer for loggingsyncbool// use sync or async way to record logs

The detailed description of these fields will be presented later.

Logging Functions

It supports the following functions for logging. All of these functions are thread-safe.

(*Logger) Logf(levelLevel, formatstring, v...interface{})
(*Logger) Log(levelLevel, v...interface{})
(*Logger) Criticalf(formatstring, v...interface{})
(*Logger) Critical(v...interface{})
(*Logger) Fatalf(formatstring, v...interface{})
(*Logger) Fatal(v...interface{})
(*Logger) Errorf(formatstring, v...interface{})
(*Logger) Error(v...interface{})
(*Logger) Warningf(formatstring, v...interface{})
(*Logger) Warning(v...interface{})
(*Logger) Warnf(formatstring, v...interface{})
(*Logger) Warn(v...interface{})
(*Logger) Infof(formatstring, v...interface{})
(*Logger) Info(v...interface{})
(*Logger) Debugf(formatstring, v...interface{})
(*Logger) Debug(v...interface{})
(*Logger) Notsetf(formatstring, v...interface{})
(*Logger) Notset(v...interface{})

Logger Operations

The logger supports the following operations. In these functions, SetWriter and Destroy are not thread-safe, while others are. All these functions are running in a synchronous way.

// Getter functions
(*Logger) Name() string// get name
(*Logger) TimeFormat() string// get time format
(*Logger) Level() Level// get level [this function is thread safe]
(*Logger) RecordFormat() string// get the first part of the format
(*Logger) RecordArgs() []string// get the second part of the format
(*Logger) Writer() io.Writer// get writer
(*Logger) Sync() bool// get sync or async// Setter functions
(*Logger) SetLevel(levelLevel) // set level [this function is thread safe]
(*Logger) SetWriter(out...io.Writer) // set multiple writers// Other functions
(*Logger) Flush() // flush the writer
(*Logger) Destroy() // destroy the logger

Fields Description

Name

Name field is a string, which can be written to the logging and used to separate multiple loggers. It allows two logger having the same name. There is not any default value for name.

Logging Levels

There are these levels in logging.

CRITICAL50FATALCRITICALERROR40WARNING30WARNWARNINGINFO20DEBUG10NOTSET0
Record Format

The record format is described by a string, which has two parts separated by \n. The first part describes the format of the log, and the second part lists all the fields to be shown in the log. In other word, the first part is the first parameter format of fmt.Printf(format string, v ...interface{}), and the second part describes the second parameter v of it. It is not allowed to have \n in the first part. The fields in the second part are separated by comma ,, while extra blank spaces are allowed. An example of the format string is

constBasicFormat="%s [%6s] %30s - %s\n name,levelname,time,message"

which is the pre-defined BasicFormat used by BasicLogger() and SimpleLogger().

It supports the following fields for the second part of the format.

"name"string%s// name of the logger"seqid"uint64%d// sequence number"levelno"int32%d// level number"levelname"string%s// level name"created"int64%d// starting time of the logger"nsecs"int64%d// nanosecond of the starting time"time"string%s// record created time"timestamp"int64%d// timestamp of record"rtime"int64%d// relative time since started"filename"string%s// source filename of the caller"pathname"string%s// filename with path"module"string%s// executable filename"lineno"int%d// line number in source code"funcname"string%s// function name of the caller"process"int%d// process id"message"string%s// logger message

The following runtime-related fields is extremely expensive and slow, please be careful when using them.

"filename"string%s// source filename of the caller"pathname"string%s// filename with path"lineno"int%d// line number in source code"funcname"string%s// function name of the caller

There are a few pre-defined values for record format.

BasicFormat="%s [%6s] %30s - %s\n name,levelname,time,message"RichFormat="%s [%6s] %d %30s - %d - %s:%s:%d - %s\n name, levelname, seqid, time, filename, funcname, lineno, message"
Time Format

We use the same time format as golang. The default time format is

DefaultTimeFormat="2006-01-02 15:04:05.999999999"// default time format
File Name, Writer, and Sync

The meaning of these fields are obvious. Filename is used to create writer. We also allow the user create a writer by herself and pass it to the logger. Sync describes whether the user would like to use synchronous or asynchronous method to write logs. true value means synchronous method, and false value means asynchronous way. We suggest you use asynchronous way because it causes extremely low extra delay by the logging functions.

Contributors

In alphabetical order

About

the logging package for golang

Resources

Stars

66 stars

Watchers

4 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

212 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

go-logging

Build StatusLicenseGoDocGo Report Card

go-logging is a high-performance logging library for golang.

  • Simple: It supports only necessary operations and easy to get started.
  • Fast: Asynchronous logging without runtime-related fields has an extremely low delay of about 800 nano-seconds.
  • Performance in my laptop as follow.
BenchmarkSync 300000 4018 ns/op
BenchmarkAsync 300000 4229 ns/op
BenchmarkBasicSync 500000 2504 ns/op
BenchmarkBasicAsync 1000000 2495 ns/op
BenchmarkPrintln 1000000 1550 ns/op

Getting Started

Installation

The step below will download the library source code to ${GOPATH}/src/github.com/ccding/go-logging.

go get github.com/ccding/go-logging/logging

Given the source code downloaded, it makes you be able to run the examples, tests, and benchmarks.

cd${GOPATH}/src/github.com/ccding/go-logging/logging
go get
go run ../example.go
go test -v -bench .

Example

go-logging is used like any other Go libraries. You can simply use the library in this way.

import"github.com/ccding/go-logging/logging"

Here is a simple example.

package main
import (
"github.com/ccding/go-logging/logging"
)
funcmain() {
logger, _:=logging.SimpleLogger("main")
logger.Error("this is a test from error")
logger.Destroy()
}

Configuration

Construction Functions

It has the following functions to create a logger.

// with BasicFormat and writing to stdoutSimpleLogger(namestring) (*Logger, error)
// with BasicFormat and writing to DefaultFileNameBasicLogger(namestring) (*Logger, error)
// with RichFormatand writing to DefaultFileNameRichLogger(namestring) (*Logger, error)
// with detailed configuration and writing to fileFileLogger(namestring, levelLevel, formatstring, timeFormatstring, filestring, syncbool) (*Logger, error)
// with detailed configuration and writing to a writerWriterLogger(namestring, levelLevel, formatstring, timeFormatstring, outio.Writer, syncbool) (*Logger, error)
// read configurations from a config fileConfigLogger(filenamestring) (*Logger, error)

The meanings of these fields are

namestring// logger namelevelLevel// record level higher than this will be printedformatstring// format configurationtimeFormatstring// format for timefilestring// file name for loggingoutio.Writer// writer for loggingsyncbool// use sync or async way to record logs

The detailed description of these fields will be presented later.

Logging Functions

It supports the following functions for logging. All of these functions are thread-safe.

(*Logger) Logf(levelLevel, formatstring, v...interface{})
(*Logger) Log(levelLevel, v...interface{})
(*Logger) Criticalf(formatstring, v...interface{})
(*Logger) Critical(v...interface{})
(*Logger) Fatalf(formatstring, v...interface{})
(*Logger) Fatal(v...interface{})
(*Logger) Errorf(formatstring, v...interface{})
(*Logger) Error(v...interface{})
(*Logger) Warningf(formatstring, v...interface{})
(*Logger) Warning(v...interface{})
(*Logger) Warnf(formatstring, v...interface{})
(*Logger) Warn(v...interface{})
(*Logger) Infof(formatstring, v...interface{})
(*Logger) Info(v...interface{})
(*Logger) Debugf(formatstring, v...interface{})
(*Logger) Debug(v...interface{})
(*Logger) Notsetf(formatstring, v...interface{})
(*Logger) Notset(v...interface{})

Logger Operations

The logger supports the following operations. In these functions, SetWriter and Destroy are not thread-safe, while others are. All these functions are running in a synchronous way.

// Getter functions
(*Logger) Name() string// get name
(*Logger) TimeFormat() string// get time format
(*Logger) Level() Level// get level [this function is thread safe]
(*Logger) RecordFormat() string// get the first part of the format
(*Logger) RecordArgs() []string// get the second part of the format
(*Logger) Writer() io.Writer// get writer
(*Logger) Sync() bool// get sync or async// Setter functions
(*Logger) SetLevel(levelLevel) // set level [this function is thread safe]
(*Logger) SetWriter(out...io.Writer) // set multiple writers// Other functions
(*Logger) Flush() // flush the writer
(*Logger) Destroy() // destroy the logger

Fields Description

Name

Name field is a string, which can be written to the logging and used to separate multiple loggers. It allows two logger having the same name. There is not any default value for name.

Logging Levels

There are these levels in logging.

CRITICAL50FATALCRITICALERROR40WARNING30WARNWARNINGINFO20DEBUG10NOTSET0
Record Format

The record format is described by a string, which has two parts separated by \n. The first part describes the format of the log, and the second part lists all the fields to be shown in the log. In other word, the first part is the first parameter format of fmt.Printf(format string, v ...interface{}), and the second part describes the second parameter v of it. It is not allowed to have \n in the first part. The fields in the second part are separated by comma ,, while extra blank spaces are allowed. An example of the format string is

constBasicFormat="%s [%6s] %30s - %s\n name,levelname,time,message"

which is the pre-defined BasicFormat used by BasicLogger() and SimpleLogger().

It supports the following fields for the second part of the format.

"name"string%s// name of the logger"seqid"uint64%d// sequence number"levelno"int32%d// level number"levelname"string%s// level name"created"int64%d// starting time of the logger"nsecs"int64%d// nanosecond of the starting time"time"string%s// record created time"timestamp"int64%d// timestamp of record"rtime"int64%d// relative time since started"filename"string%s// source filename of the caller"pathname"string%s// filename with path"module"string%s// executable filename"lineno"int%d// line number in source code"funcname"string%s// function name of the caller"process"int%d// process id"message"string%s// logger message

The following runtime-related fields is extremely expensive and slow, please be careful when using them.

"filename"string%s// source filename of the caller"pathname"string%s// filename with path"lineno"int%d// line number in source code"funcname"string%s// function name of the caller

There are a few pre-defined values for record format.

BasicFormat="%s [%6s] %30s - %s\n name,levelname,time,message"RichFormat="%s [%6s] %d %30s - %d - %s:%s:%d - %s\n name, levelname, seqid, time, filename, funcname, lineno, message"
Time Format

We use the same time format as golang. The default time format is

DefaultTimeFormat="2006-01-02 15:04:05.999999999"// default time format
File Name, Writer, and Sync

The meaning of these fields are obvious. Filename is used to create writer. We also allow the user create a writer by herself and pass it to the logger. Sync describes whether the user would like to use synchronous or asynchronous method to write logs. true value means synchronous method, and false value means asynchronous way. We suggest you use asynchronous way because it causes extremely low extra delay by the logging functions.

Contributors

In alphabetical order

About

the logging package for golang

Resources

Stars

66 stars

Watchers

4 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

212 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

go-logging

Build StatusLicenseGoDocGo Report Card

go-logging is a high-performance logging library for golang.

  • Simple: It supports only necessary operations and easy to get started.
  • Fast: Asynchronous logging without runtime-related fields has an extremely low delay of about 800 nano-seconds.
  • Performance in my laptop as follow.
BenchmarkSync 300000 4018 ns/op
BenchmarkAsync 300000 4229 ns/op
BenchmarkBasicSync 500000 2504 ns/op
BenchmarkBasicAsync 1000000 2495 ns/op
BenchmarkPrintln 1000000 1550 ns/op

Getting Started

Installation

The step below will download the library source code to ${GOPATH}/src/github.com/ccding/go-logging.

go get github.com/ccding/go-logging/logging

Given the source code downloaded, it makes you be able to run the examples, tests, and benchmarks.

cd${GOPATH}/src/github.com/ccding/go-logging/logging
go get
go run ../example.go
go test -v -bench .

Example

go-logging is used like any other Go libraries. You can simply use the library in this way.

import"github.com/ccding/go-logging/logging"

Here is a simple example.

package main
import (
"github.com/ccding/go-logging/logging"
)
funcmain() {
logger, _:=logging.SimpleLogger("main")
logger.Error("this is a test from error")
logger.Destroy()
}

Configuration

Construction Functions

It has the following functions to create a logger.

// with BasicFormat and writing to stdoutSimpleLogger(namestring) (*Logger, error)
// with BasicFormat and writing to DefaultFileNameBasicLogger(namestring) (*Logger, error)
// with RichFormatand writing to DefaultFileNameRichLogger(namestring) (*Logger, error)
// with detailed configuration and writing to fileFileLogger(namestring, levelLevel, formatstring, timeFormatstring, filestring, syncbool) (*Logger, error)
// with detailed configuration and writing to a writerWriterLogger(namestring, levelLevel, formatstring, timeFormatstring, outio.Writer, syncbool) (*Logger, error)
// read configurations from a config fileConfigLogger(filenamestring) (*Logger, error)

The meanings of these fields are

namestring// logger namelevelLevel// record level higher than this will be printedformatstring// format configurationtimeFormatstring// format for timefilestring// file name for loggingoutio.Writer// writer for loggingsyncbool// use sync or async way to record logs

The detailed description of these fields will be presented later.

Logging Functions

It supports the following functions for logging. All of these functions are thread-safe.

(*Logger) Logf(levelLevel, formatstring, v...interface{})
(*Logger) Log(levelLevel, v...interface{})
(*Logger) Criticalf(formatstring, v...interface{})
(*Logger) Critical(v...interface{})
(*Logger) Fatalf(formatstring, v...interface{})
(*Logger) Fatal(v...interface{})
(*Logger) Errorf(formatstring, v...interface{})
(*Logger) Error(v...interface{})
(*Logger) Warningf(formatstring, v...interface{})
(*Logger) Warning(v...interface{})
(*Logger) Warnf(formatstring, v...interface{})
(*Logger) Warn(v...interface{})
(*Logger) Infof(formatstring, v...interface{})
(*Logger) Info(v...interface{})
(*Logger) Debugf(formatstring, v...interface{})
(*Logger) Debug(v...interface{})
(*Logger) Notsetf(formatstring, v...interface{})
(*Logger) Notset(v...interface{})

Logger Operations

The logger supports the following operations. In these functions, SetWriter and Destroy are not thread-safe, while others are. All these functions are running in a synchronous way.

// Getter functions
(*Logger) Name() string// get name
(*Logger) TimeFormat() string// get time format
(*Logger) Level() Level// get level [this function is thread safe]
(*Logger) RecordFormat() string// get the first part of the format
(*Logger) RecordArgs() []string// get the second part of the format
(*Logger) Writer() io.Writer// get writer
(*Logger) Sync() bool// get sync or async// Setter functions
(*Logger) SetLevel(levelLevel) // set level [this function is thread safe]
(*Logger) SetWriter(out...io.Writer) // set multiple writers// Other functions
(*Logger) Flush() // flush the writer
(*Logger) Destroy() // destroy the logger

Fields Description

Name

Name field is a string, which can be written to the logging and used to separate multiple loggers. It allows two logger having the same name. There is not any default value for name.

Logging Levels

There are these levels in logging.

CRITICAL50FATALCRITICALERROR40WARNING30WARNWARNINGINFO20DEBUG10NOTSET0
Record Format

The record format is described by a string, which has two parts separated by \n. The first part describes the format of the log, and the second part lists all the fields to be shown in the log. In other word, the first part is the first parameter format of fmt.Printf(format string, v ...interface{}), and the second part describes the second parameter v of it. It is not allowed to have \n in the first part. The fields in the second part are separated by comma ,, while extra blank spaces are allowed. An example of the format string is

constBasicFormat="%s [%6s] %30s - %s\n name,levelname,time,message"

which is the pre-defined BasicFormat used by BasicLogger() and SimpleLogger().

It supports the following fields for the second part of the format.

"name"string%s// name of the logger"seqid"uint64%d// sequence number"levelno"int32%d// level number"levelname"string%s// level name"created"int64%d// starting time of the logger"nsecs"int64%d// nanosecond of the starting time"time"string%s// record created time"timestamp"int64%d// timestamp of record"rtime"int64%d// relative time since started"filename"string%s// source filename of the caller"pathname"string%s// filename with path"module"string%s// executable filename"lineno"int%d// line number in source code"funcname"string%s// function name of the caller"process"int%d// process id"message"string%s// logger message

The following runtime-related fields is extremely expensive and slow, please be careful when using them.

"filename"string%s// source filename of the caller"pathname"string%s// filename with path"lineno"int%d// line number in source code"funcname"string%s// function name of the caller

There are a few pre-defined values for record format.

BasicFormat="%s [%6s] %30s - %s\n name,levelname,time,message"RichFormat="%s [%6s] %d %30s - %d - %s:%s:%d - %s\n name, levelname, seqid, time, filename, funcname, lineno, message"
Time Format

We use the same time format as golang. The default time format is

DefaultTimeFormat="2006-01-02 15:04:05.999999999"// default time format
File Name, Writer, and Sync

The meaning of these fields are obvious. Filename is used to create writer. We also allow the user create a writer by herself and pass it to the logger. Sync describes whether the user would like to use synchronous or asynchronous method to write logs. true value means synchronous method, and false value means asynchronous way. We suggest you use asynchronous way because it causes extremely low extra delay by the logging functions.

Contributors

In alphabetical order

About

the logging package for golang

Resources

Stars

66 stars

Watchers

4 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Latest commit

History

212 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

go-logging

Build StatusLicenseGoDocGo Report Card

go-logging is a high-performance logging library for golang.

  • Simple: It supports only necessary operations and easy to get started.
  • Fast: Asynchronous logging without runtime-related fields has an extremely low delay of about 800 nano-seconds.
  • Performance in my laptop as follow.
BenchmarkSync 300000 4018 ns/op
BenchmarkAsync 300000 4229 ns/op
BenchmarkBasicSync 500000 2504 ns/op
BenchmarkBasicAsync 1000000 2495 ns/op
BenchmarkPrintln 1000000 1550 ns/op

Getting Started

Installation

The step below will download the library source code to ${GOPATH}/src/github.com/ccding/go-logging.

go get github.com/ccding/go-logging/logging

Given the source code downloaded, it makes you be able to run the examples, tests, and benchmarks.

cd${GOPATH}/src/github.com/ccding/go-logging/logging
go get
go run ../example.go
go test -v -bench .

Example

go-logging is used like any other Go libraries. You can simply use the library in this way.

import"github.com/ccding/go-logging/logging"

Here is a simple example.

package main
import (
"github.com/ccding/go-logging/logging"
)
funcmain() {
logger, _:=logging.SimpleLogger("main")
logger.Error("this is a test from error")
logger.Destroy()
}

Configuration

Construction Functions

It has the following functions to create a logger.

// with BasicFormat and writing to stdoutSimpleLogger(namestring) (*Logger, error)
// with BasicFormat and writing to DefaultFileNameBasicLogger(namestring) (*Logger, error)
// with RichFormatand writing to DefaultFileNameRichLogger(namestring) (*Logger, error)
// with detailed configuration and writing to fileFileLogger(namestring, levelLevel, formatstring, timeFormatstring, filestring, syncbool) (*Logger, error)
// with detailed configuration and writing to a writerWriterLogger(namestring, levelLevel, formatstring, timeFormatstring, outio.Writer, syncbool) (*Logger, error)
// read configurations from a config fileConfigLogger(filenamestring) (*Logger, error)

The meanings of these fields are

namestring// logger namelevelLevel// record level higher than this will be printedformatstring// format configurationtimeFormatstring// format for timefilestring// file name for loggingoutio.Writer// writer for loggingsyncbool// use sync or async way to record logs

The detailed description of these fields will be presented later.

Logging Functions

It supports the following functions for logging. All of these functions are thread-safe.

(*Logger) Logf(levelLevel, formatstring, v...interface{})
(*Logger) Log(levelLevel, v...interface{})
(*Logger) Criticalf(formatstring, v...interface{})
(*Logger) Critical(v...interface{})
(*Logger) Fatalf(formatstring, v...interface{})
(*Logger) Fatal(v...interface{})
(*Logger) Errorf(formatstring, v...interface{})
(*Logger) Error(v...interface{})
(*Logger) Warningf(formatstring, v...interface{})
(*Logger) Warning(v...interface{})
(*Logger) Warnf(formatstring, v...interface{})
(*Logger) Warn(v...interface{})
(*Logger) Infof(formatstring, v...interface{})
(*Logger) Info(v...interface{})
(*Logger) Debugf(formatstring, v...interface{})
(*Logger) Debug(v...interface{})
(*Logger) Notsetf(formatstring, v...interface{})
(*Logger) Notset(v...interface{})

Logger Operations

The logger supports the following operations. In these functions, SetWriter and Destroy are not thread-safe, while others are. All these functions are running in a synchronous way.

// Getter functions
(*Logger) Name() string// get name
(*Logger) TimeFormat() string// get time format
(*Logger) Level() Level// get level [this function is thread safe]
(*Logger) RecordFormat() string// get the first part of the format
(*Logger) RecordArgs() []string// get the second part of the format
(*Logger) Writer() io.Writer// get writer
(*Logger) Sync() bool// get sync or async// Setter functions
(*Logger) SetLevel(levelLevel) // set level [this function is thread safe]
(*Logger) SetWriter(out...io.Writer) // set multiple writers// Other functions
(*Logger) Flush() // flush the writer
(*Logger) Destroy() // destroy the logger

Fields Description

Name

Name field is a string, which can be written to the logging and used to separate multiple loggers. It allows two logger having the same name. There is not any default value for name.

Logging Levels

There are these levels in logging.

CRITICAL50FATALCRITICALERROR40WARNING30WARNWARNINGINFO20DEBUG10NOTSET0
Record Format

The record format is described by a string, which has two parts separated by \n. The first part describes the format of the log, and the second part lists all the fields to be shown in the log. In other word, the first part is the first parameter format of fmt.Printf(format string, v ...interface{}), and the second part describes the second parameter v of it. It is not allowed to have \n in the first part. The fields in the second part are separated by comma ,, while extra blank spaces are allowed. An example of the format string is

constBasicFormat="%s [%6s] %30s - %s\n name,levelname,time,message"

which is the pre-defined BasicFormat used by BasicLogger() and SimpleLogger().

It supports the following fields for the second part of the format.

"name"string%s// name of the logger"seqid"uint64%d// sequence number"levelno"int32%d// level number"levelname"string%s// level name"created"int64%d// starting time of the logger"nsecs"int64%d// nanosecond of the starting time"time"string%s// record created time"timestamp"int64%d// timestamp of record"rtime"int64%d// relative time since started"filename"string%s// source filename of the caller"pathname"string%s// filename with path"module"string%s// executable filename"lineno"int%d// line number in source code"funcname"string%s// function name of the caller"process"int%d// process id"message"string%s// logger message

The following runtime-related fields is extremely expensive and slow, please be careful when using them.

"filename"string%s// source filename of the caller"pathname"string%s// filename with path"lineno"int%d// line number in source code"funcname"string%s// function name of the caller

There are a few pre-defined values for record format.

BasicFormat="%s [%6s] %30s - %s\n name,levelname,time,message"RichFormat="%s [%6s] %d %30s - %d - %s:%s:%d - %s\n name, levelname, seqid, time, filename, funcname, lineno, message"
Time Format

We use the same time format as golang. The default time format is

DefaultTimeFormat="2006-01-02 15:04:05.999999999"// default time format
File Name, Writer, and Sync

The meaning of these fields are obvious. Filename is used to create writer. We also allow the user create a writer by herself and pass it to the logger. Sync describes whether the user would like to use synchronous or asynchronous method to write logs. true value means synchronous method, and false value means asynchronous way. We suggest you use asynchronous way because it causes extremely low extra delay by the logging functions.

Contributors

In alphabetical order

About

the logging package for golang

Resources

Stars

66 stars

Watchers

4 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

212 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

go-logging

Build StatusLicenseGoDocGo Report Card

go-logging is a high-performance logging library for golang.

  • Simple: It supports only necessary operations and easy to get started.
  • Fast: Asynchronous logging without runtime-related fields has an extremely low delay of about 800 nano-seconds.
  • Performance in my laptop as follow.
BenchmarkSync 300000 4018 ns/op
BenchmarkAsync 300000 4229 ns/op
BenchmarkBasicSync 500000 2504 ns/op
BenchmarkBasicAsync 1000000 2495 ns/op
BenchmarkPrintln 1000000 1550 ns/op

Getting Started

Installation

The step below will download the library source code to ${GOPATH}/src/github.com/ccding/go-logging.

go get github.com/ccding/go-logging/logging

Given the source code downloaded, it makes you be able to run the examples, tests, and benchmarks.

cd${GOPATH}/src/github.com/ccding/go-logging/logging
go get
go run ../example.go
go test -v -bench .

Example

go-logging is used like any other Go libraries. You can simply use the library in this way.

import"github.com/ccding/go-logging/logging"

Here is a simple example.

package main
import (
"github.com/ccding/go-logging/logging"
)
funcmain() {
logger, _:=logging.SimpleLogger("main")
logger.Error("this is a test from error")
logger.Destroy()
}

Configuration

Construction Functions

It has the following functions to create a logger.

// with BasicFormat and writing to stdoutSimpleLogger(namestring) (*Logger, error)
// with BasicFormat and writing to DefaultFileNameBasicLogger(namestring) (*Logger, error)
// with RichFormatand writing to DefaultFileNameRichLogger(namestring) (*Logger, error)
// with detailed configuration and writing to fileFileLogger(namestring, levelLevel, formatstring, timeFormatstring, filestring, syncbool) (*Logger, error)
// with detailed configuration and writing to a writerWriterLogger(namestring, levelLevel, formatstring, timeFormatstring, outio.Writer, syncbool) (*Logger, error)
// read configurations from a config fileConfigLogger(filenamestring) (*Logger, error)

The meanings of these fields are

namestring// logger namelevelLevel// record level higher than this will be printedformatstring// format configurationtimeFormatstring// format for timefilestring// file name for loggingoutio.Writer// writer for loggingsyncbool// use sync or async way to record logs

The detailed description of these fields will be presented later.

Logging Functions

It supports the following functions for logging. All of these functions are thread-safe.

(*Logger) Logf(levelLevel, formatstring, v...interface{})
(*Logger) Log(levelLevel, v...interface{})
(*Logger) Criticalf(formatstring, v...interface{})
(*Logger) Critical(v...interface{})
(*Logger) Fatalf(formatstring, v...interface{})
(*Logger) Fatal(v...interface{})
(*Logger) Errorf(formatstring, v...interface{})
(*Logger) Error(v...interface{})
(*Logger) Warningf(formatstring, v...interface{})
(*Logger) Warning(v...interface{})
(*Logger) Warnf(formatstring, v...interface{})
(*Logger) Warn(v...interface{})
(*Logger) Infof(formatstring, v...interface{})
(*Logger) Info(v...interface{})
(*Logger) Debugf(formatstring, v...interface{})
(*Logger) Debug(v...interface{})
(*Logger) Notsetf(formatstring, v...interface{})
(*Logger) Notset(v...interface{})

Logger Operations

The logger supports the following operations. In these functions, SetWriter and Destroy are not thread-safe, while others are. All these functions are running in a synchronous way.

// Getter functions
(*Logger) Name() string// get name
(*Logger) TimeFormat() string// get time format
(*Logger) Level() Level// get level [this function is thread safe]
(*Logger) RecordFormat() string// get the first part of the format
(*Logger) RecordArgs() []string// get the second part of the format
(*Logger) Writer() io.Writer// get writer
(*Logger) Sync() bool// get sync or async// Setter functions
(*Logger) SetLevel(levelLevel) // set level [this function is thread safe]
(*Logger) SetWriter(out...io.Writer) // set multiple writers// Other functions
(*Logger) Flush() // flush the writer
(*Logger) Destroy() // destroy the logger

Fields Description

Name

Name field is a string, which can be written to the logging and used to separate multiple loggers. It allows two logger having the same name. There is not any default value for name.

Logging Levels

There are these levels in logging.

CRITICAL50FATALCRITICALERROR40WARNING30WARNWARNINGINFO20DEBUG10NOTSET0
Record Format

The record format is described by a string, which has two parts separated by \n. The first part describes the format of the log, and the second part lists all the fields to be shown in the log. In other word, the first part is the first parameter format of fmt.Printf(format string, v ...interface{}), and the second part describes the second parameter v of it. It is not allowed to have \n in the first part. The fields in the second part are separated by comma ,, while extra blank spaces are allowed. An example of the format string is

constBasicFormat="%s [%6s] %30s - %s\n name,levelname,time,message"

which is the pre-defined BasicFormat used by BasicLogger() and SimpleLogger().

It supports the following fields for the second part of the format.

"name"string%s// name of the logger"seqid"uint64%d// sequence number"levelno"int32%d// level number"levelname"string%s// level name"created"int64%d// starting time of the logger"nsecs"int64%d// nanosecond of the starting time"time"string%s// record created time"timestamp"int64%d// timestamp of record"rtime"int64%d// relative time since started"filename"string%s// source filename of the caller"pathname"string%s// filename with path"module"string%s// executable filename"lineno"int%d// line number in source code"funcname"string%s// function name of the caller"process"int%d// process id"message"string%s// logger message

The following runtime-related fields is extremely expensive and slow, please be careful when using them.

"filename"string%s// source filename of the caller"pathname"string%s// filename with path"lineno"int%d// line number in source code"funcname"string%s// function name of the caller

There are a few pre-defined values for record format.

BasicFormat="%s [%6s] %30s - %s\n name,levelname,time,message"RichFormat="%s [%6s] %d %30s - %d - %s:%s:%d - %s\n name, levelname, seqid, time, filename, funcname, lineno, message"
Time Format

We use the same time format as golang. The default time format is

DefaultTimeFormat="2006-01-02 15:04:05.999999999"// default time format
File Name, Writer, and Sync

The meaning of these fields are obvious. Filename is used to create writer. We also allow the user create a writer by herself and pass it to the logger. Sync describes whether the user would like to use synchronous or asynchronous method to write logs. true value means synchronous method, and false value means asynchronous way. We suggest you use asynchronous way because it causes extremely low extra delay by the logging functions.

Contributors

In alphabetical order

About

the logging package for golang

Resources

Stars

66 stars

Watchers

4 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

212 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

go-logging

Build StatusLicenseGoDocGo Report Card

go-logging is a high-performance logging library for golang.

  • Simple: It supports only necessary operations and easy to get started.
  • Fast: Asynchronous logging without runtime-related fields has an extremely low delay of about 800 nano-seconds.
  • Performance in my laptop as follow.
BenchmarkSync 300000 4018 ns/op
BenchmarkAsync 300000 4229 ns/op
BenchmarkBasicSync 500000 2504 ns/op
BenchmarkBasicAsync 1000000 2495 ns/op
BenchmarkPrintln 1000000 1550 ns/op

Getting Started

Installation

The step below will download the library source code to ${GOPATH}/src/github.com/ccding/go-logging.

go get github.com/ccding/go-logging/logging

Given the source code downloaded, it makes you be able to run the examples, tests, and benchmarks.

cd${GOPATH}/src/github.com/ccding/go-logging/logging
go get
go run ../example.go
go test -v -bench .

Example

go-logging is used like any other Go libraries. You can simply use the library in this way.

import"github.com/ccding/go-logging/logging"

Here is a simple example.

package main
import (
"github.com/ccding/go-logging/logging"
)
funcmain() {
logger, _:=logging.SimpleLogger("main")
logger.Error("this is a test from error")
logger.Destroy()
}

Configuration

Construction Functions

It has the following functions to create a logger.

// with BasicFormat and writing to stdoutSimpleLogger(namestring) (*Logger, error)
// with BasicFormat and writing to DefaultFileNameBasicLogger(namestring) (*Logger, error)
// with RichFormatand writing to DefaultFileNameRichLogger(namestring) (*Logger, error)
// with detailed configuration and writing to fileFileLogger(namestring, levelLevel, formatstring, timeFormatstring, filestring, syncbool) (*Logger, error)
// with detailed configuration and writing to a writerWriterLogger(namestring, levelLevel, formatstring, timeFormatstring, outio.Writer, syncbool) (*Logger, error)
// read configurations from a config fileConfigLogger(filenamestring) (*Logger, error)

The meanings of these fields are

namestring// logger namelevelLevel// record level higher than this will be printedformatstring// format configurationtimeFormatstring// format for timefilestring// file name for loggingoutio.Writer// writer for loggingsyncbool// use sync or async way to record logs

The detailed description of these fields will be presented later.

Logging Functions

It supports the following functions for logging. All of these functions are thread-safe.

(*Logger) Logf(levelLevel, formatstring, v...interface{})
(*Logger) Log(levelLevel, v...interface{})
(*Logger) Criticalf(formatstring, v...interface{})
(*Logger) Critical(v...interface{})
(*Logger) Fatalf(formatstring, v...interface{})
(*Logger) Fatal(v...interface{})
(*Logger) Errorf(formatstring, v...interface{})
(*Logger) Error(v...interface{})
(*Logger) Warningf(formatstring, v...interface{})
(*Logger) Warning(v...interface{})
(*Logger) Warnf(formatstring, v...interface{})
(*Logger) Warn(v...interface{})
(*Logger) Infof(formatstring, v...interface{})
(*Logger) Info(v...interface{})
(*Logger) Debugf(formatstring, v...interface{})
(*Logger) Debug(v...interface{})
(*Logger) Notsetf(formatstring, v...interface{})
(*Logger) Notset(v...interface{})

Logger Operations

The logger supports the following operations. In these functions, SetWriter and Destroy are not thread-safe, while others are. All these functions are running in a synchronous way.

// Getter functions
(*Logger) Name() string// get name
(*Logger) TimeFormat() string// get time format
(*Logger) Level() Level// get level [this function is thread safe]
(*Logger) RecordFormat() string// get the first part of the format
(*Logger) RecordArgs() []string// get the second part of the format
(*Logger) Writer() io.Writer// get writer
(*Logger) Sync() bool// get sync or async// Setter functions
(*Logger) SetLevel(levelLevel) // set level [this function is thread safe]
(*Logger) SetWriter(out...io.Writer) // set multiple writers// Other functions
(*Logger) Flush() // flush the writer
(*Logger) Destroy() // destroy the logger

Fields Description

Name

Name field is a string, which can be written to the logging and used to separate multiple loggers. It allows two logger having the same name. There is not any default value for name.

Logging Levels

There are these levels in logging.

CRITICAL50FATALCRITICALERROR40WARNING30WARNWARNINGINFO20DEBUG10NOTSET0
Record Format

The record format is described by a string, which has two parts separated by \n. The first part describes the format of the log, and the second part lists all the fields to be shown in the log. In other word, the first part is the first parameter format of fmt.Printf(format string, v ...interface{}), and the second part describes the second parameter v of it. It is not allowed to have \n in the first part. The fields in the second part are separated by comma ,, while extra blank spaces are allowed. An example of the format string is

constBasicFormat="%s [%6s] %30s - %s\n name,levelname,time,message"

which is the pre-defined BasicFormat used by BasicLogger() and SimpleLogger().

It supports the following fields for the second part of the format.

"name"string%s// name of the logger"seqid"uint64%d// sequence number"levelno"int32%d// level number"levelname"string%s// level name"created"int64%d// starting time of the logger"nsecs"int64%d// nanosecond of the starting time"time"string%s// record created time"timestamp"int64%d// timestamp of record"rtime"int64%d// relative time since started"filename"string%s// source filename of the caller"pathname"string%s// filename with path"module"string%s// executable filename"lineno"int%d// line number in source code"funcname"string%s// function name of the caller"process"int%d// process id"message"string%s// logger message

The following runtime-related fields is extremely expensive and slow, please be careful when using them.

"filename"string%s// source filename of the caller"pathname"string%s// filename with path"lineno"int%d// line number in source code"funcname"string%s// function name of the caller

There are a few pre-defined values for record format.

BasicFormat="%s [%6s] %30s - %s\n name,levelname,time,message"RichFormat="%s [%6s] %d %30s - %d - %s:%s:%d - %s\n name, levelname, seqid, time, filename, funcname, lineno, message"
Time Format

We use the same time format as golang. The default time format is

DefaultTimeFormat="2006-01-02 15:04:05.999999999"// default time format
File Name, Writer, and Sync

The meaning of these fields are obvious. Filename is used to create writer. We also allow the user create a writer by herself and pass it to the logger. Sync describes whether the user would like to use synchronous or asynchronous method to write logs. true value means synchronous method, and false value means asynchronous way. We suggest you use asynchronous way because it causes extremely low extra delay by the logging functions.

Contributors

In alphabetical order

About

the logging package for golang

Resources

Stars

66 stars

Watchers

4 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Latest commit

History

212 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

go-logging

Build StatusLicenseGoDocGo Report Card

go-logging is a high-performance logging library for golang.

  • Simple: It supports only necessary operations and easy to get started.
  • Fast: Asynchronous logging without runtime-related fields has an extremely low delay of about 800 nano-seconds.
  • Performance in my laptop as follow.
BenchmarkSync 300000 4018 ns/op
BenchmarkAsync 300000 4229 ns/op
BenchmarkBasicSync 500000 2504 ns/op
BenchmarkBasicAsync 1000000 2495 ns/op
BenchmarkPrintln 1000000 1550 ns/op

Getting Started

Installation

The step below will download the library source code to ${GOPATH}/src/github.com/ccding/go-logging.

go get github.com/ccding/go-logging/logging

Given the source code downloaded, it makes you be able to run the examples, tests, and benchmarks.

cd${GOPATH}/src/github.com/ccding/go-logging/logging
go get
go run ../example.go
go test -v -bench .

Example

go-logging is used like any other Go libraries. You can simply use the library in this way.

import"github.com/ccding/go-logging/logging"

Here is a simple example.

package main
import (
"github.com/ccding/go-logging/logging"
)
funcmain() {
logger, _:=logging.SimpleLogger("main")
logger.Error("this is a test from error")
logger.Destroy()
}

Configuration

Construction Functions

It has the following functions to create a logger.

// with BasicFormat and writing to stdoutSimpleLogger(namestring) (*Logger, error)
// with BasicFormat and writing to DefaultFileNameBasicLogger(namestring) (*Logger, error)
// with RichFormatand writing to DefaultFileNameRichLogger(namestring) (*Logger, error)
// with detailed configuration and writing to fileFileLogger(namestring, levelLevel, formatstring, timeFormatstring, filestring, syncbool) (*Logger, error)
// with detailed configuration and writing to a writerWriterLogger(namestring, levelLevel, formatstring, timeFormatstring, outio.Writer, syncbool) (*Logger, error)
// read configurations from a config fileConfigLogger(filenamestring) (*Logger, error)

The meanings of these fields are

namestring// logger namelevelLevel// record level higher than this will be printedformatstring// format configurationtimeFormatstring// format for timefilestring// file name for loggingoutio.Writer// writer for loggingsyncbool// use sync or async way to record logs

The detailed description of these fields will be presented later.

Logging Functions

It supports the following functions for logging. All of these functions are thread-safe.

(*Logger) Logf(levelLevel, formatstring, v...interface{})
(*Logger) Log(levelLevel, v...interface{})
(*Logger) Criticalf(formatstring, v...interface{})
(*Logger) Critical(v...interface{})
(*Logger) Fatalf(formatstring, v...interface{})
(*Logger) Fatal(v...interface{})
(*Logger) Errorf(formatstring, v...interface{})
(*Logger) Error(v...interface{})
(*Logger) Warningf(formatstring, v...interface{})
(*Logger) Warning(v...interface{})
(*Logger) Warnf(formatstring, v...interface{})
(*Logger) Warn(v...interface{})
(*Logger) Infof(formatstring, v...interface{})
(*Logger) Info(v...interface{})
(*Logger) Debugf(formatstring, v...interface{})
(*Logger) Debug(v...interface{})
(*Logger) Notsetf(formatstring, v...interface{})
(*Logger) Notset(v...interface{})

Logger Operations

The logger supports the following operations. In these functions, SetWriter and Destroy are not thread-safe, while others are. All these functions are running in a synchronous way.

// Getter functions
(*Logger) Name() string// get name
(*Logger) TimeFormat() string// get time format
(*Logger) Level() Level// get level [this function is thread safe]
(*Logger) RecordFormat() string// get the first part of the format
(*Logger) RecordArgs() []string// get the second part of the format
(*Logger) Writer() io.Writer// get writer
(*Logger) Sync() bool// get sync or async// Setter functions
(*Logger) SetLevel(levelLevel) // set level [this function is thread safe]
(*Logger) SetWriter(out...io.Writer) // set multiple writers// Other functions
(*Logger) Flush() // flush the writer
(*Logger) Destroy() // destroy the logger

Fields Description

Name

Name field is a string, which can be written to the logging and used to separate multiple loggers. It allows two logger having the same name. There is not any default value for name.

Logging Levels

There are these levels in logging.

CRITICAL50FATALCRITICALERROR40WARNING30WARNWARNINGINFO20DEBUG10NOTSET0
Record Format

The record format is described by a string, which has two parts separated by \n. The first part describes the format of the log, and the second part lists all the fields to be shown in the log. In other word, the first part is the first parameter format of fmt.Printf(format string, v ...interface{}), and the second part describes the second parameter v of it. It is not allowed to have \n in the first part. The fields in the second part are separated by comma ,, while extra blank spaces are allowed. An example of the format string is

constBasicFormat="%s [%6s] %30s - %s\n name,levelname,time,message"

which is the pre-defined BasicFormat used by BasicLogger() and SimpleLogger().

It supports the following fields for the second part of the format.

"name"string%s// name of the logger"seqid"uint64%d// sequence number"levelno"int32%d// level number"levelname"string%s// level name"created"int64%d// starting time of the logger"nsecs"int64%d// nanosecond of the starting time"time"string%s// record created time"timestamp"int64%d// timestamp of record"rtime"int64%d// relative time since started"filename"string%s// source filename of the caller"pathname"string%s// filename with path"module"string%s// executable filename"lineno"int%d// line number in source code"funcname"string%s// function name of the caller"process"int%d// process id"message"string%s// logger message

The following runtime-related fields is extremely expensive and slow, please be careful when using them.

"filename"string%s// source filename of the caller"pathname"string%s// filename with path"lineno"int%d// line number in source code"funcname"string%s// function name of the caller

There are a few pre-defined values for record format.

BasicFormat="%s [%6s] %30s - %s\n name,levelname,time,message"RichFormat="%s [%6s] %d %30s - %d - %s:%s:%d - %s\n name, levelname, seqid, time, filename, funcname, lineno, message"
Time Format

We use the same time format as golang. The default time format is

DefaultTimeFormat="2006-01-02 15:04:05.999999999"// default time format
File Name, Writer, and Sync

The meaning of these fields are obvious. Filename is used to create writer. We also allow the user create a writer by herself and pass it to the logger. Sync describes whether the user would like to use synchronous or asynchronous method to write logs. true value means synchronous method, and false value means asynchronous way. We suggest you use asynchronous way because it causes extremely low extra delay by the logging functions.

Contributors

In alphabetical order

About

the logging package for golang

Resources

Stars

66 stars

Watchers

4 watching

Forks

Releases

Packages

Used by

Contributors

Languages