log4go

package module
v1.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 29, 2022 License: Apache-2.0 Imports: 14 Imported by: 10

README

log4go

a logkit like as log4j with go language

license

Introduce

This project is come from an unmaintained fork, the branch can see http://log4go.googlecode.com

  • left only so it doesn't break imports.
  • some enhancement if to need

Feature

This project's idea is come from log4j, and support a log toolkit for golang.

  • Support system output like stdout, stderr and so on
  • Support file system log output
  • Support network log output, in TCP/UDP, support reconnect while break down from log server
  • Support customized the LoggerAppender
  • Support configuration with XML
  • Support configuration with Json

Usage

  • Add log4go with the following import
import "github.com/gohutool/log4go"
  • Support Xml configuration
./examples/example.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <appender enabled="true" name="console">
    <type>console</type>
    <pattern>[%D %T] [%L] (%S) %M</pattern>
    <!-- level is (:?FINEST|FINE|DEBUG|TRACE|INFO|WARNING|ERROR) -->
  </appender>
  <appender enabled="true" name="file">
    <type>file</type>
    <pattern>[%D %T] [%L] (%S) %M</pattern>
    <property name="filename">test.log</property>
    <!--
       %T - Time (15:04:05 MST)
       %t - Time (15:04)
       %D - Date (2006/01/02)
       %d - Date (01/02/06)
       %L - Level (FNST, FINE, DEBG, TRAC, WARN, EROR, CRIT)
       %S - Source
       %M - Message
       It ignores unknown format strings (and removes them)
       Recommended: "[%D %T] [%L] (%S) %M"
    -->
    <property name="rotate">false</property> 
    <!-- true enables log rotation, otherwise append -->
    <property name="maxsize">0M</property> 
    <!-- \d+[KMG]? Suffixes are in terms of 2**10 -->
    <property name="maxlines">0K</property> 
    <!-- \d+[KMG]? Suffixes are in terms of thousands -->
    <property name="daily">true</property> 
    <!-- Automatically rotates when a log message is written after midnight -->
  </appender>
  <appender enabled="true" name="testfile">
    <type>file</type>
    <pattern>[%D %T] [%L] (%S) %M</pattern>
    <property name="filename">trace.xml</property>
    <property name="rotate">false</property> 
    <!-- true enables log rotation, otherwise append -->
    <property name="maxsize">100M</property> 
    <!-- \d+[KMG]? Suffixes are in terms of 2**10 -->
    <property name="maxrecords">6K</property> 
    <!-- \d+[KMG]? Suffixes are in terms of thousands -->
    <property name="daily">false</property> 
    <!-- Automatically rotates when a log message is written after midnight -->
  </appender>
  <!-- enabled=false means this logger won't actually be created -->
  <appender enabled="false" name="logstash">
    <type>socket</type>
    <pattern>[%D %T] [%L] (%S) %M</pattern>
    <property name="endpoint">192.168.1.255:12124</property> 
    <!-- recommend UDP broadcast -->
    <property name="protocol">udp</property> 
    <!-- tcp or udp -->
  </appender>
  
  <!-- 这个就是自定义的一个logger -->
  <!-- 输出级别是info级别及以上的日志,不要怕,StreamOperateFile已经过滤,只输出info级别的日志 -->
  <!-- additivity 这个默认是true,即继承父类 root logger -->
  <!-- 也就是说,你的这个日志也会在root的logger里面输出的,我这里配置false,就是不继承,各走各的。 -->
  <!-- appender-ref 也就是说这个logger的输出目的地是哪里,ref就是关联到上面声明的一个file,一个console -->
  <logger name="com.ginghan">
    <level>info</level>
    <appender-ref ref="file" />
    <appender-ref ref="console" />
  </logger>

  <logger name="com.hello">
    <level>info</level>
    <appender-ref ref="console" />
    <appender-ref ref="file" />
  </logger>

  <!-- 输出级别是info级别及以上的日志,下面的ref关联的两个appender没有filter设置,
  所以,info及以上的日志都是会输出到这2个appender的 -->
  <root>
    <level>info</level>
    <appender-ref ref="testfile" />
    <appender-ref ref="logstash" />
  </root>

</configuration>
  • Support Json configuration
{
	"appenders": [
		{
			"enabled": "true",
			"name": "console",
			"type": "console",
			"pattern": "[%D %T] [%L] (%S) %M",
			"properties": null
		},
		{
			"enabled": "true",
			"name": "file",
			"type": "file",
			"pattern": "[%D %T] [%L] (%S) %M",
			"properties": [
				{
					"name": "filename",
					"value": "test.log"
				},
				{
					"name": "rotate",
					"value": "false"
				},
				{
					"name": "maxsize",
					"value": "0M"
				},
				{
					"name": "maxlines",
					"value": "0K"
				},
				{
					"name": "daily",
					"value": "true"
				}
			]
		},
		{
			"enabled": "true",
			"name": "testfile",
			"type": "file",
			"pattern": "[%D %T] [%L] (%S) %M",
			"properties": [
				{
					"name": "filename",
					"value": "trace.xml"
				},
				{
					"name": "rotate",
					"value": "false"
				},
				{
					"name": "maxsize",
					"value": "100M"
				},
				{
					"name": "maxrecords",
					"value": "6K"
				},
				{
					"name": "daily",
					"value": "false"
				}
			]
		},
		{
			"enabled": "false",
			"name": "logstash",
			"type": "socket",
			"pattern": "[%D %T] [%L] (%S) %M",
			"properties": [
				{
					"name": "endpoint",
					"value": "192.168.1.255:12124"
				},
				{
					"name": "protocol",
					"value": "udp"
				}
			]
		}
	],
	"root": {
		"level": "info",
		"appender-refs": [
			{
				"appender": "testfile"
			},
			{
				"appender": "logstash"
			}
		]
	},
	"loggers": [
		{
			"name": "Sample",
			"level": "info",
			"appender-refs": [
				{
					"appender": "file"
				},
				{
					"appender": "console"
				}
			]
		},
		{
			"name": "Demo",
			"level": "info",
			"appender-refs": [
				{
					"appender": "console"
				},
				{
					"appender": "file"
				}
			]
		}
	]
}
  • log4go sample

import (
	"github.com/gohutool/log4go"
	"testing"
	"time"
)

var logger = log4go.LoggerManager.GetLogger("com.hello")

func TestLoggerExample(t *testing.T) {
	log4go.LoggerManager.InitWithXML("./example.xml")
	logger.Info("hello")
	logger.Info("hello")
	time.Sleep(1 * time.Second)
	logger.Error("hello")

	time.Sleep(3 * time.Second)
}
  • sample output
=== RUN   TestLoggerExample
[2022/04/06 15:17:59 CST 299] [INFO][com.hello] (github.com/gohutool/log4go/examples.TestLoggerExample:73) hello
[2022/04/06 15:17:59 CST 299] [INFO][com.hello] (github.com/gohutool/log4go/examples.TestLoggerExample:72) hello
[2022/04/06 15:18:00 CST 299] [EROR][com.hello] (github.com/gohutool/log4go/examples.TestLoggerExample:75) hello
--- PASS: TestLoggerExample (4.00s)
PASS

Debugger finished with the exit code 0
  • FileLoggerAppender output

File log output snapshot

Socket Support
  • UDP Support
  <appender enabled="true" name="logstash">
  <!-- enabled=false means this logger won't actually be created -->
    <type>socket</type>
    <pattern>[%D %T %m] [%L][%l] (%S) %M</pattern>
    <property name="endpoint">192.168.56.1:12124</property> 
    <!-- recommend UDP broadcast -->
    <property name="protocol">udp</property> <!-- tcp or udp -->
  </appender>

  <root>
    <level>info</level>
    <appender-ref ref="console" />
    <appender-ref ref="logstash" />
  </root>

UDP Socket log output snapshot

  • TCP Support
  <appender enabled="true" name="logstash">
    <!-- enabled=false means this logger won't actually be created -->
    <type>socket</type>
    <pattern>[%D %T %m] [%L][%l] (%S) %M</pattern>
    <property name="endpoint">192.168.56.1:12124</property>
    <!-- recommend UDP broadcast -->
    <property name="protocol">tcp</property> <!-- tcp or udp -->
    <property name="retry">-1</property> 
    <!-- 断线重连,设置为负数,反复重连,设置为正数,重连测试后失败 -->
    <property name="interval">30</property> 
    <!-- 失败重连的间隔时间,默认30秒 -->
    <property name="check">false</property> 
    <!-- 启动日志是否检查连接成功,如果检查,不成功会失败 -->
  </appender>
  
  <root>
    <level>info</level>
    <appender-ref ref="console" />
    <appender-ref ref="logstash" />
  </root>

TCP Socket log output snapshot

Acknowledgements:

  • pomack For providing awesome patches to bring log4go up to the latest Go spec

Documentation

Index

Constants

View Source
const (
	L4G_VERSION = "log4go-v1.0.1"
	L4G_MAJOR   = 1
	L4G_MINOR   = 0
	L4G_BUILD   = 1
)
View Source
const (
	FORMAT_DEFAULT = "[%D %T %m] [%L] (%S) %M"
	FORMAT_SHORT   = "[%t %d] [%L] %M"
	FORMAT_ABBREV  = "[%L] %M"
)

Variables

View Source
var DefaultPatternConverter = &defaultPatternConverter{}
View Source
var (
	// LogBufferLength specifies how many log messages a particular log4go
	// logger can buffer at a time before writing them.
	LogBufferLength = 32
)

***** Variables *****

View Source
var LogMetrics = &logMetrics{LogCount: 0, IgnoreCount: 0, AppendCount: 0}
View Source
var LoggerAppenderFactory = &loggerAppenderFactory{}
View Source
var LoggerManager = &loggerManager{_debug: false}

Functions

func BuildFormatString added in v1.0.0

func BuildFormatString(format string, a ...any) string

func BuildString

func BuildString(a ...any) string

func LeftPad added in v1.0.0

func LeftPad(str string, limit int, placeholder rune) string

Types

type AppenderConfig

type AppenderConfig struct {
	Enabled  string             `xml:"enabled,attr" json:"enabled"`
	Name     string             `xml:"name,attr" json:"name"`
	Type     string             `xml:"type" json:"type"`
	Pattern  string             `xml:"pattern" json:"pattern"`
	Property []AppenderProperty `xml:"property" json:"properties"`
}

type AppenderProperty

type AppenderProperty struct {
	Name  string `xml:"name,attr" json:"name"`
	Value string `xml:",chardata" json:"value"`
}

type AppenderRef

type AppenderRef struct {
	Ref string `xml:"ref,attr" json:"appender"`
}

type ConsoleLoggerAppender

type ConsoleLoggerAppender struct {
	// contains filtered or unexported fields
}

func (*ConsoleLoggerAppender) Close

func (cla *ConsoleLoggerAppender) Close() error

Close This should clean up anything lingering about the LogWriter, as it is called before the LogWriter is removed. LogWrite should not be called after Close.

func (*ConsoleLoggerAppender) Init

func (cla *ConsoleLoggerAppender) Init(pattern string, property []AppenderProperty) error

func (*ConsoleLoggerAppender) LogWrite

func (cla *ConsoleLoggerAppender) LogWrite(rec LogRecord) error

LogWrite This will be called to log a LogRecord message.

func (*ConsoleLoggerAppender) Start

func (cla *ConsoleLoggerAppender) Start() error

type FileLoggerAppender

type FileLoggerAppender struct {
	// contains filtered or unexported fields
}

func (*FileLoggerAppender) Close

func (fla *FileLoggerAppender) Close() error

Close This should clean up anything lingering about the LogWriter, as it is called before the LogWriter is removed. LogWrite should not be called after Close.

func (*FileLoggerAppender) Init

func (fla *FileLoggerAppender) Init(pattern string, property []AppenderProperty) error

func (*FileLoggerAppender) LogWrite

func (fla *FileLoggerAppender) LogWrite(rec LogRecord) error

LogWrite This will be called to log a LogRecord message.

func (*FileLoggerAppender) Start

func (fla *FileLoggerAppender) Start() error

type Level

type Level int
const (
	FINEST Level = iota
	FINE
	DEBUG
	TRACE
	INFO
	WARNING
	ERROR
	CRITICAL
)

func (Level) String

func (l Level) String() string

type LevelText

type LevelText string
const (
	FINEST_TXT   LevelText = "FINEST"
	FINE_TXT     LevelText = "FINE"
	DEBUG_TXT    LevelText = "DEBUG"
	TRACE_TXT    LevelText = "TRACE"
	INFO_TXT     LevelText = "INFO"
	WARNING_TXT  LevelText = "WARNING"
	ERROR_TXT    LevelText = "ERROR"
	CRITICAL_TXT LevelText = "CRITICAL"
)

func (LevelText) Level

func (l LevelText) Level() Level

func (LevelText) String

func (l LevelText) String() string

type LogRecord

type LogRecord struct {
	TagName string    // The tag name
	Level   Level     // The log level
	Created time.Time // The time at which the log message was created (nanoseconds)
	Source  string    // The message source
	Message string    // The log message
}

A LogRecord contains all the pertinent information for each message

type Logger

type Logger struct {
	Name string
}

func (Logger) Critical

func (c Logger) Critical(arg0 any, args ...any) error

func (Logger) Debug

func (c Logger) Debug(arg0 any, args ...any) error

func (Logger) Error

func (c Logger) Error(arg0 any, args ...any) error

func (Logger) Fine

func (c Logger) Fine(arg0 any, args ...any) error

func (Logger) Finest

func (c Logger) Finest(arg0 any, args ...any) error

func (Logger) Info

func (c Logger) Info(arg0 any, args ...any) error

func (Logger) Trace

func (c Logger) Trace(arg0 any, args ...any) error

func (Logger) Warning

func (c Logger) Warning(arg0 any, args ...any) error

type LoggerAppender

type LoggerAppender interface {
	Init(pattern string, property []AppenderProperty) error

	Start() error

	// LogWrite
	//This will be called to log a LogRecord message.
	LogWrite(rec LogRecord) error

	// Close
	// This should clean up anything lingering about the LogWriter, as it is called before
	// the LogWriter is removed.  LogWrite should not be called after Close.
	Close() error
}

type LoggerAppenderReference

type LoggerAppenderReference struct {
	// contains filtered or unexported fields
}

type LoggerConfig

type LoggerConfig struct {
	Name     string        `xml:"name,attr" json:"name"`
	Level    string        `xml:"level" json:"level"`
	Appender []AppenderRef `xml:"appender-ref" json:"appender-refs"`
}

type LoggerConfiguration

type LoggerConfiguration struct {
	Appender []AppenderConfig `xml:"appender" json:"appenders"`
	Root     RootLoggerConfig `xml:"root" json:"root"`
	Logger   []LoggerConfig   `xml:"logger" json:"loggers"`
}

func LoadJson added in v1.0.0

func LoadJson(content string) LoggerConfiguration

func LoadJsonConfigurationProperties added in v1.0.0

func LoadJsonConfigurationProperties(filename string) LoggerConfiguration

func LoadXML

func LoadXML(content string) LoggerConfiguration

func LoadXMLConfigurationProperties

func LoadXMLConfigurationProperties(filename string) LoggerConfiguration

type PatternConverter added in v1.0.0

type PatternConverter interface {
	FormatLogRecord(pattern string, rec LogRecord) string
}

type RootLoggerConfig

type RootLoggerConfig struct {
	Level    string        `xml:"level" json:"level"`
	Appender []AppenderRef `xml:"appender-ref" json:"appender-refs"`
}

type SocketLoggerAppender

type SocketLoggerAppender struct {
	// contains filtered or unexported fields
}

func (*SocketLoggerAppender) Close

func (sla *SocketLoggerAppender) Close() error

Close This should clean up anything lingering about the LogWriter, as it is called before the LogWriter is removed. LogWrite should not be called after Close.

func (*SocketLoggerAppender) Init

func (sla *SocketLoggerAppender) Init(pattern string, property []AppenderProperty) error

func (*SocketLoggerAppender) LogWrite

func (sla *SocketLoggerAppender) LogWrite(rec LogRecord) error

LogWrite This will be called to log a LogRecord message.

func (*SocketLoggerAppender) Start

func (sla *SocketLoggerAppender) Start() error

type TimeSlice added in v1.0.0

type TimeSlice struct {
	LastUpdateSeconds int64
	// contains filtered or unexported fields
}

func (*TimeSlice) GetTimeSlice added in v1.0.0

func (t *TimeSlice) GetTimeSlice(time time.Time)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL