Skip to content

Enable developers to extend custom logging #786

@abeyum

Description

@abeyum

Hello,

I'd like to make an enhancement to gh-ost by adding the functionality to have logs write outside of standard output (i.e. cloud, centralized logging, etc.). Hence, I'd like to create an interface in which a developer could extend and write their own custom logs to where they see fit. The default logging behavior would log as expected with the outbrain/golib/log package, resulting in no changes to how logging is conduct at the moment (code samples provided below). The proposed modifications:

  1. Create a Logger interface
  2. Add a field Log to MigrationContext
  3. Assign a default logger to NewMigrationContext.Log by leveraging outbrain/golib/log
  4. Make updates to use the NewMigrationContext.Log where necessary

Logger interface

type Logger interface {
	Debug(args ...interface{})
	Debugf(format string, args ...interface{})
	Info(args ...interface{})
	Infof(format string, args ...interface{})
	Warning(args ...interface{}) error
	Warningf(format string, args ...interface{}) error
	Error(args ...interface{}) error
	Errorf(format string, args ...interface{}) error
	Errore(err error) error
	Fatal(args ...interface{}) error
	Fatalf(format string, args ...interface{}) error
	Fatale(err error) error
	SetLevel(level log.LogLevel)
	SetPrintStackTrace(printStackTraceFlag bool)
}

Add Log to MigrationContext

	MigrationRangeMaxValues          *sql.ColumnValues
	Iteration                        int64
	MigrationIterationRangeMinValues *sql.ColumnValues
	MigrationIterationRangeMaxValues *sql.ColumnValues
	ForceTmpTableName                string

	recentBinlogCoordinates mysql.BinlogCoordinates

	Log Logger
}

Assign a default logger

		configMutex:                         &sync.Mutex{},
		pointOfInterestTimeMutex:            &sync.Mutex{},
		ColumnRenameMap:                     make(map[string]string),
		PanicAbort:                          make(chan error),
		Log:				     NewDefaultLogger(),
	}
}

DefaultLogger

package base

import (
	"github.com/outbrain/golib/log"
)

type simpleLogger struct{}

func NewDefaultLogger() *simpleLogger {
	return &simpleLogger{}
}

func (*simpleLogger) Debug(args ...interface{}) {
	log.Debug(args[0].(string), args[1:])
	return
}

func (*simpleLogger) Debugf(format string, args ...interface{}) {
	log.Debugf(format, args...)
	return
}

func (*simpleLogger) Info(args ...interface{}) {
	log.Info(args[0].(string), args[1:])
	return
}

func (*simpleLogger) Infof(format string, args ...interface{}) {
	log.Infof(format, args...)
	return
}

func (*simpleLogger) Warning(args ...interface{}) error {
	return log.Warning(args[0].(string), args[1:])
}

func (*simpleLogger) Warningf(format string, args ...interface{}) error {
	return log.Warningf(format, args...)
}

func (*simpleLogger) Error(args ...interface{}) error {
	return log.Error(args[0].(string), args[1:])
}

func (*simpleLogger) Errorf(format string, args ...interface{}) error {
	return log.Errorf(format, args...)
}

func (*simpleLogger) Errore(err error) error {
	return log.Errore(err)
}

func (*simpleLogger) Fatal(args ...interface{}) error {
	return log.Fatal(args[0].(string), args[1:])
}

func (*simpleLogger) Fatalf(format string, args ...interface{}) error {
	return log.Fatalf(format, args...)
}

func (*simpleLogger) Fatale(err error) error {
	return log.Fatale(err)
}

func (*simpleLogger) SetLevel(level log.LogLevel) {
	log.SetLevel(level)
	return
}

func (*simpleLogger) SetPrintStackTrace(printStackTraceFlag bool) {
	log.SetPrintStackTrace(printStackTraceFlag)
	return
}

Sample usage of NewMigrationContext.Log

this.migrationContext.Log.Infof(...)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions