Logrusly: Loggly Hooks for GO Logrus logger

Loggly Hooks for Logrus :walrus:


package main

import (

var logglyToken string = "YOUR_LOGGLY_TOKEN"

func main() {
    log := logrus.New()
    hook := logrusly.NewLogglyHook(logglyToken, "www.hostname.com", logrus.WarnLevel, "tag1", "tag2")

        "name": "joe",
        "age":  42,
    }).Error("Hello world!")

    // Flush is automatic for panic/fatal
    // Just make sure to Flush() before exiting or you may loose up to 5 seconds
    // worth of messages.

Author: Sebest
Source Code: https://github.com/sebest/logrusly 
License: MIT License

#go #golang #logger #logging 

What is GEEK

Buddha Community

Logrusly: Loggly Hooks for GO Logrus logger

Logrusly: Loggly Hooks for GO Logrus logger

Loggly Hooks for Logrus :walrus:


package main

import (

var logglyToken string = "YOUR_LOGGLY_TOKEN"

func main() {
    log := logrus.New()
    hook := logrusly.NewLogglyHook(logglyToken, "www.hostname.com", logrus.WarnLevel, "tag1", "tag2")

        "name": "joe",
        "age":  42,
    }).Error("Hello world!")

    // Flush is automatic for panic/fatal
    // Just make sure to Flush() before exiting or you may loose up to 5 seconds
    // worth of messages.

Author: Sebest
Source Code: https://github.com/sebest/logrusly 
License: MIT License

#go #golang #logger #logging 

Fannie  Zemlak

Fannie Zemlak


What's new in the go 1.15

Go announced Go 1.15 version on 11 Aug 2020. Highlighted updates and features include Substantial improvements to the Go linker, Improved allocation for small objects at high core counts, X.509 CommonName deprecation, GOPROXY supports skipping proxies that return errors, New embedded tzdata package, Several Core Library improvements and more.

As Go promise for maintaining backward compatibility. After upgrading to the latest Go 1.15 version, almost all existing Golang applications or programs continue to compile and run as older Golang version.

#go #golang #go 1.15 #go features #go improvement #go package #go new features

Go-logger: Simple Logger for Go Programs


A simple go logger for easy logging in your programs. Allows setting custom format for messages.


Example Output


go get github.com/apsdehal/go-logger

Use go get -u to update the package.


Example program demonstrates how to use the logger. See below for formatting instructions.

package main

import (

func main () {
    // Get the instance for logger class, "test" is the module name, 1 is used to
    // state if we want coloring
    // Third option is optional and is instance of type io.Writer, defaults to os.Stderr
    log, err := logger.New("test", 1, os.Stdout)
    if err != nil {
        panic(err) // Check for error

    // Critically log critical
    log.Critical("This is Critical!")
    log.CriticalF("%+v", err)
    // You can also use fmt compliant naming scheme such as log.Criticalf, log.Panicf etc
    // with small 'f'
    // Debug
    // Since default logging level is Info this won't print anything
    log.Debug("This is Debug!")
    log.DebugF("Here are some numbers: %d %d %f", 10, -3, 3.14)
    // Give the Warning
    log.Warning("This is Warning!")
    log.WarningF("This is Warning!")
    // Show the error
    log.Error("This is Error!")
    log.ErrorF("This is Error!")
    // Notice
    log.Notice("This is Notice!")
    log.NoticeF("%s %s", "This", "is Notice!")
    // Show the info
    log.Info("This is Info!")
    log.InfoF("This is %s!", "Info")

    log.StackAsError("Message before printing stack");

    // Show warning with format
    log.SetFormat("[%{module}] [%{level}] %{message}")
    log.Warning("This is Warning!") // output: "[test] [WARNING] This is Warning!"
    // Also you can set your format as default format for all new loggers
    log2, _ := logger.New("pkg", 1, os.Stdout)
    log2.Error("This is Error!") // output: "This is Error!"

    // Use log levels to set your log priority
    // This will be printed
    log2.Debug("This is debug!")
    // This won't be printed
    log2.Info("This is an error!")


By default all log messages have format that you can see above (on pic). But you can override the default format and set format that you want.

You can do it for Logger instance (after creating logger) ...

log, _ := logger.New("pkgname", 1)

... or for package


If you do it for package, all existing loggers will print log messages with format that these used already. But all newest loggers (which will be created after changing format for package) will use your specified format.

But anyway after this, you can still set format of message for specific Logger instance.

Format of log message must contains verbs that represent some info about current log entry. Ofc, format can contain not only verbs but also something else (for example text, digits, symbols, etc)

Format verbs:

You can use the following verbs:

%{id}           - means number of current log message
%{module}       - means module name (that you passed to func New())
%{time}            - means current time in format "2006-01-02 15:04:05"
%{time:format}    - means current time in format that you want
                    (supports all formats supported by go package "time")
%{level}        - means level name (upper case) of log message ("ERROR", "DEBUG", etc)
%{lvl}            - means first 3 letters of level name (upper case) of log message ("ERR", "DEB", etc)
%{file}         - means name of file in what you wanna write log
%{filename}        - means the same as %{file}
%{line}            - means line number of file in what you wanna write log
%{message}        - means your log message

Non-existent verbs (like %{nonex-verb} or %{}) will be replaced by an empty string. Invalid verbs (like %{inv-verb) will be treated as plain text.



  • go test logger to run test on logger.
  • go test -bench=. for benchmarks.


Thanks goes to all go-loggers out there which I used as reference.


Following contributors have made major contributions to go-logger:

Author: Apsdehal
Source Code: https://github.com/apsdehal/go-logger 
License: BSD-3-Clause License

#go #golang #logger #logging 

Go-log: A Logger, for Go!


A logger, for Go!

It's sort of log and code.google.com/p/log4go compatible, so in most cases can be used without any code changes.

Breaking change

go-log was inconsistent with the default Go 'log' package, and log.Fatal calls didn't trigger an os.Exit(1).

This has been fixed in the current release of go-log, which might break backwards compatibility.

You can disable the fix by setting ExitOnFatal to false, e.g.

log.Logger().ExitOnFatal = false

Getting started

Install go-log:

go get github.com/ian-kent/go-log/log

Use the logger in your application:


// Pass a log message and arguments directly
log.Debug("Example log message: %s", "example arg")

// Pass a function which returns a log message and arguments
log.Debug(func(){[]interface{}{"Example log message: %s", "example arg"}})
log.Debug(func(i ...interface{}){[]interface{}{"Example log message: %s", "example arg"}})

You can also get the logger instance:

logger := log.Logger()

Or get a named logger instance:

logger := log.Logger("foo.bar")

Log levels

The default log level is DEBUG.

To get the current log level:

level := logger.Level()

Or to set the log level:

// From a LogLevel

// From a string

Log appenders

The default log appender is appenders.Console(), which logs the raw message to STDOUT.

To get the current log appender:

appender := logger.Appender()

If the appender is nil, the parent loggers appender will be used instead.

If the appender eventually resolves to nil, log data will be silently dropped.

You can set the log appender:


Rolling file appender

Similar to log4j's rolling file appender, you can use

// Append to (or create) file
logger.SetAppender(appenders.RollingFile("filename.log", true))

// Truncate (or create) file
logger.SetAppender(appenders.RollingFile("filename.log", false))

You can also control the number of log files which are kept:

r := appenders.RollingFile("filename.log", true)
r.MaxBackupIndex = 2 // filename.log, filename.log.1, filename.log.2

And the maximum log file size (in bytes):

r := appenders.RollingFile("filename.log", true)
r.MaxFileSize = 1024 // 1KB, defaults to 100MB

Fluentd appender

The fluentd appender lets you write log data directly to fluentd:


It uses github.com/t-k/fluent-logger-golang.

The tag is currently fixed to 'go-log', and the data structure sent to fluentd is simple:

  message: "<output from layout>"


Each appender has its own layout. This allows the log data to be transformed as it is written to the appender.

The default layout is layout.Basic(), which passes the log message and its arguments through fmt.Sprintf.

To get the current log appender layout:

appender := logger.Appender()
layout := appender.Layout()

To set the log appender layout:


You can also use layout.Pattern(pattern string), which accepts a pattern format similar to log4j:

%cThe package the log statement is in
%CCurrently also the package the log statement is in
%dThe current date/time, using time.Now().String()
%FThe filename the log statement is in
%lThe location of the log statement, e.g. package/somefile.go:12
%LThe line number the log statement is on
%mThe log message and its arguments formatted with fmt.Sprintf
%nA new-line character
%pPriority - the log level
%rms since logger was created

Logger inheritance

Loggers are namespaced with a ., following similar rules to Log4j.

If you create a logger named foo, it will automatically inherit the log settings (levels and appender) of the root logger.

If you then create a logger named foo.bar, it will inherit the log settings of foo, which in turn inherits the log settings from the root logger.

You can break this by setting the log level or setting an appender on a child logger, e.g.:

logger := log.Logger("foo.bar")

If you then created a logger named foo.bar.qux, it would inherit the trace level and console appender of the foo.bar logger.


  • log4j configuration support
    • .properties
    • .xml
    • .json
  • layouts
    • fixmes/todos in pattern layout
  • appenders
    • add socket appender
    • fixmes/todos and tests for fluentd appender
  • optimise logger creation
    • collapse loggers when parent namespace is unused
    • reorganise loggers when new child tree is created
  • add godoc documentation


Before submitting a pull request:

  • Format your code: go fmt ./...
  • Make sure tests pass: go test ./...

Author: ian-kent
Source Code: https://github.com/ian-kent/go-log 
License: MIT License

#go #golang #logger #logging 

Sqldb-logger: A Logger for Go SQL Database Driver


A logger for Go SQL database driver without modify existing *sql.DB stdlib usage.

shameless console output sample Colored console writer output above only for sample/development


  • Leveled, detailed and configurable logging.
  • Keep using (or re-use existing) *sql.DB as is.
  • Bring your own logger backend via simple log interface.
  • Trackable log output:
    • Every call has its own unique ID.
    • Prepared statement and execution will have same ID.
    • On execution/result error, it will include the query, arguments, params, and related IDs.


go get -u -v github.com/simukti/sqldb-logger

Version pinning using dependency manager such as Mod or Dep is highly recommended.


As a start, Logger is just a simple interface:

type Logger interface {
    Log(ctx context.Context, level Level, msg string, data map[string]interface{})

There are 4 included basic implementation that uses well-known JSON structured logger for quickstart:

Note: those adapters does not use given context, you need to modify it and adjust with your needs. (example: add http request id/whatever value from context to query log when you call QueryerContext andExecerContext methods)

Then for that logger to works, you need to integrate with a compatible driver which will be used by *sql.DB.


Re-use from existing *sql.DB driver, this is the simplest way:

For example, from:

dsn := "username:passwd@tcp(mysqlserver:3306)/dbname?parseTime=true"
db, err := sql.Open("mysql", dsn) // db is *sql.DB
db.Ping() // to check connectivity and DSN correctness


// import sqldblogger "github.com/simukti/sqldb-logger"
// import "github.com/simukti/sqldb-logger/logadapter/zerologadapter"
dsn := "username:passwd@tcp(mysqlserver:3306)/dbname?parseTime=true"
db, err := sql.Open("mysql", dsn) // db is *sql.DB
// handle err
loggerAdapter := zerologadapter.New(zerolog.New(os.Stdout))
db = sqldblogger.OpenDriver(dsn, db.Driver(), loggerAdapter/*, using_default_options*/) // db is STILL *sql.DB
db.Ping() // to check connectivity and DSN correctness

That's it, all *sql.DB interaction now logged.


It is also possible to integrate with following public empty struct driver directly:

MySQL (go-sql-driver/mysql)

db := sqldblogger.OpenDriver(dsn, &mysql.MySQLDriver{}, loggerAdapter /*, ...options */)

PostgreSQL (lib/pq)

db := sqldblogger.OpenDriver(dsn, &pq.Driver{}, loggerAdapter /*, ...options */) 

SQLite3 (mattn/go-sqlite3)

db := sqldblogger.OpenDriver(dsn, &sqlite3.SQLiteDriver{}, loggerAdapter /*, ...options */)

Following struct drivers maybe compatible:

SQL Server (denisenkom/go-mssqldb)

db := sqldblogger.OpenDriver(dsn, &mssql.Driver{}, loggerAdapter /*, ...options */)

Oracle (mattn/go-oci8)

db := sqldblogger.OpenDriver(dsn, oci8.OCI8Driver, loggerAdapter /*, ...options */)


When using sqldblogger.OpenDriver(dsn, driver, logger, opt...) without 4th variadic argument, it will use default options.

Here is sample of OpenDriver() using all available options and use non-default value:

db = sqldblogger.OpenDriver(
    sqldblogger.WithErrorFieldname("sql_error"),                    // default: error
    sqldblogger.WithDurationFieldname("query_duration"),            // default: duration
    sqldblogger.WithTimeFieldname("log_time"),                      // default: time
    sqldblogger.WithSQLQueryFieldname("sql_query"),                 // default: query
    sqldblogger.WithSQLArgsFieldname("sql_args"),                   // default: args
    sqldblogger.WithMinimumLevel(sqldblogger.LevelTrace),           // default: LevelDebug
    sqldblogger.WithLogArguments(false),                            // default: true
    sqldblogger.WithDurationUnit(sqldblogger.DurationNanosecond),   // default: DurationMillisecond
    sqldblogger.WithTimeFormat(sqldblogger.TimeFormatRFC3339),      // default: TimeFormatUnix
    sqldblogger.WithLogDriverErrorSkip(true),                       // default: false
    sqldblogger.WithSQLQueryAsMessage(true),                        // default: false
    sqldblogger.WithUIDGenerator(sqldblogger.UIDGenerator),         // default: *defaultUID
    sqldblogger.WithConnectionIDFieldname("con_id"),                // default: conn_id
    sqldblogger.WithStatementIDFieldname("stm_id"),                 // default: stmt_id
    sqldblogger.WithTransactionIDFieldname("trx_id"),               // default: tx_id
    sqldblogger.WithWrapResult(false),                              // default: true
    sqldblogger.WithIncludeStartTime(true),                         // default: false
    sqldblogger.WithStartTimeFieldname("start_time"),               // default: start
    sqldblogger.WithPreparerLevel(sqldblogger.LevelDebug),          // default: LevelInfo
    sqldblogger.WithQueryerLevel(sqldblogger.LevelDebug),           // default: LevelInfo
    sqldblogger.WithExecerLevel(sqldblogger.LevelDebug),            // default: LevelInfo

Click here for options documentation.


I want to:

  • Keep using *sql.DB.
  • Have configurable output field.
  • Leverage structured logging.
  • Fetch and log context.Context value if needed.
  • Re-use pgx log interface.

I haven't found Go *sql.DB logger with that features, so why not created myself?



If you found a bug, typo, wrong test, idea, help with existing issue, or anything constructive.

Don't hesitate to create an issue or pull request.


  • pgx for awesome PostgreSQL driver.

Author: Simukti
Source Code: https://github.com/simukti/sqldb-logger 
License: MIT License

#go #golang #logger #sql