tower

package module
v0.8.1 Latest Latest
Warning

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

Go to latest
Published: Jan 17, 2023 License: Apache-2.0 Imports: 15 Imported by: 5

README

Tower-Go build-status-svg

Coverages

Module Type Coverage
Root tower-svg
Integrations cache-svg
bucket-svg
Extensions towerhttp-svg
towerzap-svg
towerdiscord-svg
Submodules memcache-svg
goredis-v8-svg
goredis-v9-svg
minio-v7-svg
s3-v2-svg
Utilities pool-svg
queue-svg
loader-svg

Note: this readme is still on WIP.

Overview

Tower is an opinionated Error, Logging, and Notification framework for Go.

Tower's main goal is to improve developer experience when handling errors and logging.

Tower does so by providing a common API interface for error handling, logging, and notification. It also aims to provide more information about the error, such as where the error occurred or the context of how it happens. It also optionally provides a way to enrich the error with additional information, such as a message, data, error code, and so on.

Tower does not stop there, it goes one step further by providing a way to log and send the error to a notification in one single flow.

It basically turns the flow from this:

func foo() error {
    _, err := strconv.Atoi("foo")
    if err != nil {
        err := fmt.Errorf("failed to convert string to int: %w", err)
        log.Println(err)
        notify(ctx, err)
        return err
    }
}

Into this:

func foo() error {
    _, err := strconv.Atoi("foo")
    if err != nil {
        return tower.Wrap(err).Message("failed to convert string to int").Log(ctx).Notify(ctx) // Notify and Log in one single flow
        // return tower.Wrap(err).Message("failed to convert string to int").Log(ctx)  <-- if you just want to log
        // return tower.Wrap(err).Message("failed to convert string to int").Notify(ctx)  <-- if you want to send notification.
        // return tower.Wrap(err).Message("failed to convert string to int").Freeze() <-- if you just want to enrich the error.
        // return tower.WrapFreeze(err, "failed to convert string to int") <-- short hand for above.
    }
}

I could already hear you saying "Hey I still have to write that much, what gives?"

There are already a lot of things happening behind the scenes, such as:

  • When you call tower.Wrap(err), it will automatically enrich the error with the location of the Wrap() caller, settings the log level into tower.ErrorLevel and fill the error code.
  • When you call .Log(ctx), it will make Tower to look at its own tower.Logger implementor, and sends the enriched Error to the logger.
  • When you call .Notify(ctx), it will make Tower to look at its own tower.Messenger implementors, and sends the enriched Error to the messengers.
  • When you call .Freeze(), it will make Tower transforms the mutable ErrorBuilder into an immutable Error.

There are already obvious benefits from this snippet alone. Logging and Sending Notifications are decoupled from the business logic, and the business logic is now more readable. You can also easily change or add more logging and notification to Tower itself and the changes will be reflected without modifying the business logic.

If you are working with a team, for them, it's already obvious that you already log and send notification from here when error happens. More often than not for them, it's enough. They most likely don't want to know how you log and send notification, they just want to know that you do. Hell, future you probably just want to know that your current self do it and don't care about the details.

While the first snippet fulfills above conditions, the relationship between logging and business is strictly coupled and makes refactoring a chore.

While these things can be considered "little things", they do add up and make a huge difference in the long run.

Technical Details

Error, ErrorBuilder, Entry, EntryBuilder, Logger, Messenger

All these 6 entities are the main Types you have to know when using Tower. As a user, You don't have to know how they exactly works, but knowing the idea behind them will let you get the most out of Tower framework.

ErrorBuilder

tower.ErrorBuilder is the entry point to handle errors with Tower. Whenever tower.Wrap function is called, this type is returned.

Note that tower.ErrorBuilder itself does not implement error. It holds temporary and mutable values until one of these three methods were called:

  1. .Freeze(), turns the tower.ErrorBuilder into tower.Error, which implements error.
  2. .Log(context.Context), implicitly calls .Freeze() and then calls .Log(context.Context) of the tower.Error.
  3. .Notify(context.Context, ...MessageOption), implicitly calls .Freeze(), and then calls .Notifyof the tower.Error

Realistic example of using the tower.ErrorBuilder.

func foo(s string) error {
    _, err := strconv.Atoi(s)
    if err != nil {
        return tower.
            Wrap(err).
            Message("strconv: failed to convert string to int").
            Code(400).
            Context(tower.Fields{
                "input": s,
            }).
            Log(ctx). // calls .Freeze() implicitly, turning into tower.Error, calls the Log method of tower.Error, then
                      // return the tower.Error
            Notify(ctx)
            // There are more API in tower.ErrorBuilder, consult the docs for those.
    }
}
Error

tower.Error is an extension to the native golang's error type. tower.Error is a crystallized form of values from

Afterwords

The library API design draws heavy inspiration from mongodb-go driver designs. Using Options that are split again into "Group" like options, just because of the sheer number of options available. Tower, while a lot smaller in scale, also needs such kind of flexibility. Hence the similar Options design.

Documentation

Index

Constants

View Source
const Query query = 0

Query is a namespace group that holds the tower's Query functions.

Methods and functions under Query are utilities to search values in the error stack.

Variables

View Source
var Global global

Functions

func Cast added in v0.1.10

func Cast[T any](in []T) []any

Cast turns any slice into a slice of any.

func Dbg added in v0.1.1

func Dbg[T any](a T) T

Dbg Prints the variable and returns the given item after printing. Useful for Debugging without breaking the code flow.

func DetachedContext added in v0.1.1

func DetachedContext(ctx context.Context) context.Context

DetachedContext creates a context whose lifetime is detached from the input, but the values of the context is still reachable.

DetachedContext is used by tower to send Contextes to Messengers so they are not tied to the input lifetime.

func NewTestingTower added in v0.1.10

func NewTestingTower(service Service) (*Tower, *TestingJSONLogger)

Types

type Caller

type Caller interface {
	// Function returns the function information.
	Function() *runtime.Func
	// Name returns the function name of the caller.
	Name() string
	// ShortName returns only function name of the caller.
	ShortName() string
	// ShortSource returns only the latest three items path in the File Path where the Caller comes from.
	ShortSource() string
	// String Sets this caller as `file_path:line` format.
	String() string
	// Line returns the line number of the caller.
	Line() int
	// File returns the file path of the caller.
	File() string
	// PC returns the program counter of the caller.
	PC() uintptr
	// FormatAsKey Like .String(), but runes other than letters, digits, `-` and `.` are set to `_`.
	FormatAsKey() string
}

func GetCaller

func GetCaller(depth int) Caller

GetCaller returns the caller information for who calls this function. A value of 1 will return this GetCaller location. So you may want the value to be 2 or higher if you wrap this call in another function.

Returns zero value if the caller information cannot be obtained.

type CallerHint added in v0.1.1

type CallerHint interface {
	// Caller returns the caller of this type.
	Caller() Caller
}

type CodeBlockJSONMarshaler added in v0.1.10

type CodeBlockJSONMarshaler interface {
	CodeBlockJSON() ([]byte, error)
}

type CodeHint added in v0.1.1

type CodeHint interface {
	// Gets the original code of the type.
	Code() int
}

type ContextHint added in v0.1.1

type ContextHint interface {
	// Context returns the context of this type.
	Context() []any
}

type Display

type Display interface {
	// Display returns a human-readable and rich with information for the implementer.
	Display() string
}

type DisplayWriter

type DisplayWriter interface {
	// WriteDisplay Writes the Display() string to the writer instead of being allocated as value.
	WriteDisplay(w LineWriter)
}

type Entry added in v0.1.1

type Entry interface {
	CallerHint
	CodeHint
	ContextHint
	HTTPCodeHint
	KeyHint
	LevelHint
	MessageHint
	ServiceHint
	TimeHint

	/*
		Logs this entry.
	*/
	Log(ctx context.Context) Entry
	/*
		Notifies this entry to Messengers.
	*/
	Notify(ctx context.Context, opts ...MessageOption) Entry
}

type EntryBuilder added in v0.1.1

type EntryBuilder interface {
	// Code Sets the code for this entry.
	Code(i int) EntryBuilder

	// Message Sets the message for this entry.
	//
	// In built in implementation, If args are supplied, fmt.Sprintf will be called with s as base string.
	//
	// Very unlikely you will need to set this, because tower already create the message field for you when you call tower.NewEntry.
	Message(s string, args ...any) EntryBuilder

	// Context Sets additional data that will enrich how the entry will look.
	//
	// `tower.Fields` is a type that is more integrated with built-in Messengers.
	// Using this type as Context value will often have special treatments for it.
	//
	// In built-in implementation, additional call to .Context() will make additional index, not replacing what you already set.
	//
	// Example:
	//
	// 	tower.NewEntry(msg).Code(200).Context(tower.F{"foo": "bar"}).Freeze()
	Context(ctx ...any) EntryBuilder

	// Key Sets the key for this entry. This is how Messenger will use to identify if an entry is the same as previous or not.
	//
	// In tower's built-in implementation, by default, no key is set when creating new entry.
	//
	// Usually by not setting the key, The Messenger will generate their own key for this message.
	//
	// In built in implementation, If args are supplied, fmt.Sprintf will be called with key as base string.
	Key(key string, args ...any) EntryBuilder

	// Caller Sets the caller for this entry.
	//
	// In tower's built-in implementation, by default, the caller is the location where you call `tower.NewEntry`.
	Caller(c Caller) EntryBuilder

	// Time Sets the time for this entry. By default, it's already set when you call tower.NewEntry.
	Time(time.Time) EntryBuilder

	/*
		Sets the level for this entry.

		In tower's built-in implementation, this defaults to what method you call to generate this entry.
	*/
	Level(lvl Level) EntryBuilder

	/*
		Freeze this entry. Preventing further mutations.
	*/
	Freeze() Entry
	/*
		Log this entry. Implicitly calling .Freeze() method.
	*/
	Log(ctx context.Context) Entry

	/*
		Sends this Entry to Messengers. Implicitly calling .Freeze() method.
	*/
	Notify(ctx context.Context, opts ...MessageOption) Entry
}

EntryBuilder is the builder for Entry.

func NewEntry added in v0.1.1

func NewEntry(msg string, args ...any) EntryBuilder

NewEntry Creates a new EntryBuilder. The returned EntryBuilder may be appended with values.

type EntryConstructor added in v0.1.1

type EntryConstructor interface {
	ConstructEntry(*EntryConstructorContext) EntryBuilder
}

type EntryConstructorContext added in v0.1.1

type EntryConstructorContext struct {
	Caller  Caller
	Message string
	Tower   *Tower
}

type EntryConstructorFunc added in v0.1.1

type EntryConstructorFunc func(*EntryConstructorContext) EntryBuilder

func (EntryConstructorFunc) ConstructEntry added in v0.1.1

type EntryNode added in v0.1.10

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

EntryNode is the default implementation of Entry for tower.

func (EntryNode) Caller added in v0.1.10

func (e EntryNode) Caller() Caller

Caller returns the tower.Caller of the entry.

func (EntryNode) Code added in v0.1.10

func (e EntryNode) Code() int

Code returns the original code of the type.

func (EntryNode) Context added in v0.1.10

func (e EntryNode) Context() []any

Context returns the context of the entry.

func (EntryNode) HTTPCode added in v0.1.10

func (e EntryNode) HTTPCode() int

HTTPCode return HTTP Status Code for the type.

func (EntryNode) Key added in v0.1.10

func (e EntryNode) Key() string

Key returns the key of the entry.

func (EntryNode) Level added in v0.1.10

func (e EntryNode) Level() Level

Level Gets the level of this message.

func (EntryNode) Log added in v0.1.10

func (e EntryNode) Log(ctx context.Context) Entry

Log logs the entry.

func (EntryNode) MarshalJSON added in v0.1.10

func (e EntryNode) MarshalJSON() ([]byte, error)

MarshalJSON implements the json.Marshaler interface.

func (EntryNode) Message added in v0.1.10

func (e EntryNode) Message() string

Message returns the message.

func (EntryNode) Notify added in v0.1.10

func (e EntryNode) Notify(ctx context.Context, opts ...MessageOption) Entry

Notify sends the entry to the messengers.

func (EntryNode) Service added in v0.1.10

func (e EntryNode) Service() Service

Service returns the service name of the entry.

func (EntryNode) Time added in v0.1.10

func (e EntryNode) Time() time.Time

Time returns the time of the entry.

type Error

type Error interface {
	error
	CallerHint
	CodeHint
	ContextHint
	ErrorUnwrapper
	ErrorWriter
	HTTPCodeHint
	KeyHint
	LevelHint
	MessageHint
	TimeHint
	ServiceHint

	/*
		Logs this error.
	*/
	Log(ctx context.Context) Error
	/*
		Notifies this error to Messengers.
	*/
	Notify(ctx context.Context, opts ...MessageOption) Error
}

Error is an interface providing read only values to the error, and because it's read only, this is safe for multithreaded use.

func BailFreeze added in v0.1.1

func BailFreeze(msg string, args ...any) Error

BailFreeze creates new immutable Error from simple messages.

It's a shorthand for `tower.Bail(msg, args...).Freeze()`.

func WrapFreeze added in v0.1.1

func WrapFreeze(err error, message string, args ...any) Error

WrapFreeze is a Shorthand for `tower.Wrap(err).Message(message, args...).Freeze()`

Useful when just wanting to add extra simple messages to the error chain.

type ErrorBuilder

type ErrorBuilder interface {
	/*
		Sets the error code for this error.
		This is used to identify the error type and how towerhttp will interact with this error.

		The default implementation for Tower handles code like this:

		The default value, if anything in the error implements CodeHint interface,
		use the outermost CodeHint implementer, otherwise fallsback to 500.

		`tower.Error` that is generated by tower implements CodeHinter interface,
		and thus if the error is wrapped again, the default code for this error will be the code of the wrapped `tower.Error`.

		Example:

			if err != nil {
				return tower.Wrap(err).Code(500).Freeze()
			}
	*/
	Code(i int) ErrorBuilder

	/*
		Overrides the error message for this error.

		In built in implementation, If args are supplied, fmt.Sprintf will be called with s as base string.
	*/
	Message(s string, args ...any) ErrorBuilder

	/*
		Sets the origin error for ErrorBuilder. Very unlikely to need to set this because tower.Wrap already wraps the error.
		But the api is available to set the origin error.
	*/
	Error(err error) ErrorBuilder

	/*
		Sets additional data that will enrich how the error will look.

		`tower.Fields` is a type that is well integrated with built-in Messengers.
		Using this type as Context value will have the performance more optimized when being marshaled
		or provides additional quality of life improvements without having to implement those features
		yourself. Use `tower.F` as alias for this type.

		In built-in implementation, additional call to .Context() will make additional index, not replacing what you already set.

		Example:

			tower.Wrap(err).Code(400).Context(tower.F{"foo": "bar"}).Freeze()
	*/
	Context(ctx ...any) ErrorBuilder

	/*
		Sets the key for this error. This is how Messenger will use to identify if an error is the same as previous or not.

		In tower's built-in implementation, by default, no key is set.

		Usually by not setting the key, The Messenger will generate their own.

		In built in implementation, If args are supplied, fmt.Sprintf will be called with key as base string.
	*/
	Key(key string, args ...any) ErrorBuilder

	/*
		Sets the caller for this error.

		In tower's built-in implementation, by default, the caller is the location where you call `tower.Wrap` or `tower.WrapFreeze`
	*/
	Caller(c Caller) ErrorBuilder

	/*
		Sets the level for this error.

		In tower's built-in implementation, this defaults to ErrorLevel if not set.
	*/
	Level(lvl Level) ErrorBuilder

	/*
		Sets the time for this error.

		In tower's built-in implementation, this is already set to when tower.Wrap is called.
	*/
	Time(t time.Time) ErrorBuilder

	/*
		Freeze this ErrorBuilder, preventing further mutations and set this ErrorBuilder into proper error.

		The returned Error is safe for multithreaded usage because of its immutable nature.
	*/
	Freeze() Error

	/*
		Logs this error. Implicitly calls .Freeze() on this ErrorBuilder.
	*/
	Log(ctx context.Context) Error
	/*
		Notifies this error to Messengers. Implicitly calls .Freeze() on this ErrorBuilder.
	*/
	Notify(ctx context.Context, opts ...MessageOption) Error
}

ErrorBuilder is an interface to create customizable error.

ErrorBuilder by itself is not an error type. You have to call .Freeze() method to create proper Error type.

func Bail added in v0.1.1

func Bail(msg string, args ...any) ErrorBuilder

Bail creates a new ErrorBuilder from simple messages.

If args are not empty, msg will be fed into fmt.Errorf along with the args. Otherwise, msg will be fed into `errors.New()`.

func Wrap added in v0.1.1

func Wrap(err error) ErrorBuilder

Wrap the error. The returned ErrorBuilder may be appended with values. Call .Freeze() method to turn this into proper error. Or call .Log() or .Notify() to implicitly freeze the error and do actual stuffs.

Example:

if err != nil {
  return tower.Wrap(err).Message("something went wrong").Freeze()
}

Example with Log:

if err != nil {
  return tower.Wrap(err).Message("something went wrong").Log(ctx)
}

Example with Notify:

if err != nil {
  return tower.Wrap(err).Message("something went wrong").Notify(ctx)
}

Example with Notify and Log:

if err != nil {
  return tower.Wrap(err).Message("something went wrong").Log(ctx).Notify(ctx)
}

type ErrorConstructor

type ErrorConstructor interface {
	ConstructError(*ErrorConstructorContext) ErrorBuilder
}

type ErrorConstructorContext added in v0.1.1

type ErrorConstructorContext struct {
	Err    error
	Caller Caller
	Tower  *Tower
}

type ErrorConstructorFunc added in v0.1.1

type ErrorConstructorFunc func(*ErrorConstructorContext) ErrorBuilder

func (ErrorConstructorFunc) ConstructError added in v0.1.10

type ErrorMessageContextBuilder added in v0.1.1

type ErrorMessageContextBuilder interface {
	BuildErrorMessageContext(err Error, param MessageParameter) MessageContext
}

type ErrorMessageContextBuilderFunc added in v0.1.1

type ErrorMessageContextBuilderFunc func(err Error, param MessageParameter) MessageContext

func (ErrorMessageContextBuilderFunc) BuildErrorMessageContext added in v0.1.1

func (f ErrorMessageContextBuilderFunc) BuildErrorMessageContext(err Error, param MessageParameter) MessageContext

type ErrorNode added in v0.1.10

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

ErrorNode is the implementation of the Error interface.

func (*ErrorNode) Caller added in v0.1.10

func (e *ErrorNode) Caller() Caller

Caller Gets the caller of this type.

func (*ErrorNode) Code added in v0.1.10

func (e *ErrorNode) Code() int

Code Gets the original code of the type.

func (*ErrorNode) CodeBlockJSON added in v0.1.10

func (e *ErrorNode) CodeBlockJSON() ([]byte, error)

func (*ErrorNode) Context added in v0.1.10

func (e *ErrorNode) Context() []any

Context Gets the context of this type.

func (*ErrorNode) Error added in v0.1.10

func (e *ErrorNode) Error() string

func (*ErrorNode) HTTPCode added in v0.1.10

func (e *ErrorNode) HTTPCode() int

HTTPCode Gets HTTP Status Code for the type.

func (*ErrorNode) Key added in v0.1.10

func (e *ErrorNode) Key() string

func (*ErrorNode) Level added in v0.1.10

func (e *ErrorNode) Level() Level

func (*ErrorNode) Log added in v0.1.10

func (e *ErrorNode) Log(ctx context.Context) Error

Log this error.

func (*ErrorNode) MarshalJSON added in v0.1.10

func (e *ErrorNode) MarshalJSON() ([]byte, error)

func (*ErrorNode) Message added in v0.1.10

func (e *ErrorNode) Message() string

Message Gets the Message of the type.

func (*ErrorNode) Notify added in v0.1.10

func (e *ErrorNode) Notify(ctx context.Context, opts ...MessageOption) Error

Notify this error to Messengers.

func (*ErrorNode) Service added in v0.1.10

func (e *ErrorNode) Service() Service

func (*ErrorNode) Time added in v0.1.10

func (e *ErrorNode) Time() time.Time

func (*ErrorNode) Unwrap added in v0.1.10

func (e *ErrorNode) Unwrap() error

Unwrap Returns the error that is wrapped by this error. To be used by errors.Is and errors.As functions from errors library.

func (*ErrorNode) WriteError added in v0.1.10

func (e *ErrorNode) WriteError(w LineWriter)

WriteError Writes the error.Error to the writer instead of being allocated as value.

type ErrorUnwrapper

type ErrorUnwrapper interface {
	// Unwrap Returns the error that is wrapped by this error. To be used by errors.Is and errors.As functions from errors library.
	Unwrap() error
}

type ErrorWriter

type ErrorWriter interface {
	// WriteError Writes the error.Error to the writer instead of being allocated as value.
	WriteError(w LineWriter)
}

type F added in v0.1.1

type F = Fields

F Alias to tower.Fields.

type Fields

type Fields map[string]any

func (Fields) Summary added in v0.1.1

func (f Fields) Summary() string

Summary Returns a short summary of this type.

func (Fields) WriteSummary added in v0.1.1

func (f Fields) WriteSummary(w LineWriter)

WriteSummary Writes the Summary() string to the writer instead of being allocated as value.

type Float added in v0.1.1

type Float interface {
	~float32 | ~float64
}

type HTTPCodeHint added in v0.1.1

type HTTPCodeHint interface {
	// Gets HTTP Status Code for the type.
	HTTPCode() int
}

type Integer added in v0.1.1

type Integer interface {
	Signed | Unsigned
}

type KeyHint added in v0.1.1

type KeyHint interface {
	// Key returns the key for this type.
	Key() string
}

type KeyValue added in v0.1.1

type KeyValue[K, V any] struct {
	Key   K
	Value V
}

func NewKeyValue added in v0.1.1

func NewKeyValue[K, V any](key K, value V) KeyValue[K, V]

type Level added in v0.1.1

type Level int8
const (
	DebugLevel Level = iota - 1
	InfoLevel
	WarnLevel
	ErrorLevel
	FatalLevel
	PanicLevel
)

func (Level) String added in v0.1.3

func (l Level) String() string

type LevelHint added in v0.1.1

type LevelHint interface {
	// Level returns the level of this type.
	Level() Level
}

type LineWriter added in v0.1.1

type LineWriter interface {
	io.Writer
	io.StringWriter
	// WriteNewLine Writes a predetermined new line character(s) to the writer.
	WriteLineBreak()
	// WritePrefix Writes a predetermined prefix to the writer.
	WritePrefix()
	// WriteSuffix Writes a predetermined suffix to the writer.
	WriteSuffix()
	// WriteIndent Writes Indentation characters.
	WriteIndent()
	// GetLineBreak Returns the pre-determined line break characters.
	GetLineBreak() string
	// GetPrefix Returns the pre-determined prefix.
	GetPrefix() string
	// GetSuffix Returns the pre-determined suffix.
	GetSuffix() string
	// GetIndentation Returns the pre-determined indentation.
	GetIndentation() string
}

type LineWriterBuilder added in v0.1.1

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

func NewLineWriter added in v0.1.1

func NewLineWriter(writer io.Writer) *LineWriterBuilder

NewLineWriter Creates a new LineWriterBuilder. You have to call .Build() to actually use LineWriter.

func (*LineWriterBuilder) Build added in v0.1.1

func (builder *LineWriterBuilder) Build() LineWriter

Build Turn this writer into proper LineWriter.

func (*LineWriterBuilder) Indent added in v0.1.1

func (builder *LineWriterBuilder) Indent(s string) *LineWriterBuilder

Indent Sets the Indentation.

func (*LineWriterBuilder) LineBreak added in v0.1.1

func (builder *LineWriterBuilder) LineBreak(s string) *LineWriterBuilder

LineBreak Sets the Linebreak character(s).

func (*LineWriterBuilder) Prefix added in v0.1.1

func (builder *LineWriterBuilder) Prefix(s string) *LineWriterBuilder

Prefix Sets the Prefix.

func (*LineWriterBuilder) Suffix added in v0.1.1

func (builder *LineWriterBuilder) Suffix(s string) *LineWriterBuilder

Suffix Sets the Suffix.

type Logger added in v0.1.1

type Logger interface {
	Log(ctx context.Context, entry Entry)
	LogError(ctx context.Context, err Error)
}

type MessageContext added in v0.1.1

type MessageContext interface {
	HTTPCodeHint
	CodeHint
	MessageHint
	CallerHint
	KeyHint
	LevelHint
	ServiceHint
	ContextHint
	TimeHint
	// Err returns the error item. May be nil if message contains no error.
	Err() error
	// SkipVerification If true, Sender asks for this message to always be send.
	SkipVerification() bool
	// Cooldown returns non-zero value if Sender asks for this message to be sent after this duration.
	Cooldown() time.Duration
	// Tower Gets the tower instance that created this MessageContext.
	Tower() *Tower
}

MessageContext is the context of a message.

It holds the message and data that can be sent to the Messenger's target.

type MessageContextBuilder added in v0.1.1

type MessageContextBuilder interface {
	BuildMessageContext(entry Entry, param MessageParameter) MessageContext
}

type MessageContextBuilderFunc added in v0.1.1

type MessageContextBuilderFunc func(entry Entry, param MessageParameter) MessageContext

func (MessageContextBuilderFunc) BuildMessageContext added in v0.1.1

func (f MessageContextBuilderFunc) BuildMessageContext(entry Entry, param MessageParameter) MessageContext

type MessageHint added in v0.1.1

type MessageHint interface {
	// Message returns the message of the type.
	Message() string
}

type MessageOption added in v0.1.1

type MessageOption interface {
	// contains filtered or unexported methods
}

func ExtraMessengers added in v0.1.1

func ExtraMessengers(messengers ...Messenger) MessageOption

Asks Tower to send messages to currenty registered and also send those messeges to these Messengers.

Note: MessengerNameContains messageOption will conflict with other Messenger setters messageOption, and thus only the latest messageOption will be set.

func MessageCooldown added in v0.1.1

func MessageCooldown(dur time.Duration) MessageOption

Sets the Cooldown for this Message.

func MessengerNameContains added in v0.1.1

func MessengerNameContains(s string) MessageOption

Asks Tower to only send messages to Messengers whose name contains given s.

Note: MessengerNameContains messageOption will conflict with other Messenger setters messageOption, and thus only the latest messageOption will be set.

func MessengerPrefix added in v0.1.1

func MessengerPrefix(s string) MessageOption

Asks Tower to only send messages to Messengers whose name begins with given s.

Note: MessengerPrefix messageOption will conflict with other Messenger setters messageOption, and thus only the latest messageOption will be set.

func MessengerSuffix added in v0.1.1

func MessengerSuffix(s string) MessageOption

Asks Tower to only send messages to Messengers whose name ends with given s.

Note: MessengerSuffix messageOption will conflict with other Messenger setters messageOption, and thus only the latest messageOption will be set.

func OnlyMessengerWithName added in v0.1.1

func OnlyMessengerWithName(name string) MessageOption

OnlyMessengerWithName Asks Tower to only send only to the Messenger with this name. If name is not found, Tower returns to default behaviour.

Note: OnlyMessengerWithName messageOption will conflict with other Messenger setters messageOption, and thus only the latest messageOption will be set.

func OnlyTheseMessengers added in v0.1.1

func OnlyTheseMessengers(m ...Messenger) MessageOption

func OnlyThisMessenger added in v0.1.1

func OnlyThisMessenger(m Messenger) MessageOption

Asks Tower to only send only to this Messenger.

Note: OnlyThisMessenger messageOption will conflict with other Messenger setters messageOption, and thus only the latest messageOption will be set.

func SkipMessageVerification added in v0.1.1

func SkipMessageVerification(b bool) MessageOption

SkipMessageVerification Asks the Messengers to Skip cooldown verifications and just send the message.

type MessageOptionFunc added in v0.1.1

type MessageOptionFunc func(*messageOption)

type MessageParameter added in v0.1.1

type MessageParameter interface {
	SkipVerification() bool
	Cooldown() time.Duration
	Tower() *Tower
}

type Messenger added in v0.1.1

type Messenger interface {
	// Returns the name of the Messenger.
	Name() string
	// Sends notification.
	SendMessage(ctx context.Context, msg MessageContext)

	// Waits until all message in the queue or until given channel is received.
	//
	// Implementer must exit the function as soon as possible when this ctx is canceled.
	Wait(ctx context.Context) error
}

type Messengers added in v0.1.1

type Messengers map[string]Messenger

func (Messengers) Clone added in v0.1.1

func (c Messengers) Clone() Messengers

type NoopLogger added in v0.1.1

type NoopLogger struct{}

NoopLogger that does nothing. The default logger that Tower uses.

func (NoopLogger) Log added in v0.1.1

func (NoopLogger) Log(ctx context.Context, entry Entry)

func (NoopLogger) LogError added in v0.1.1

func (NoopLogger) LogError(ctx context.Context, err Error)

type NoopTracer added in v0.1.1

type NoopTracer struct{}

NoopTracer is a tracer that does nothing.

func (NoopTracer) CaptureTrace added in v0.1.1

func (n NoopTracer) CaptureTrace(ctx context.Context) Trace

type Ordered added in v0.1.1

type Ordered interface {
	Integer | Float | ~string
}

type Service added in v0.1.1

type Service struct {
	Name        string `json:"name,omitempty"`
	Environment string `json:"environment,omitempty"`
	Repository  string `json:"repository,omitempty"`
	Branch      string `json:"branch,omitempty"`
	Type        string `json:"type,omitempty"`
	Version     string `json:"version,omitempty"`
}

func (Service) IsNil added in v0.1.1

func (s Service) IsNil() bool

func (Service) String added in v0.1.1

func (s Service) String() string

type ServiceHint added in v0.1.1

type ServiceHint interface {
	// Service returns the service information.
	Service() Service
}

type Signed added in v0.1.1

type Signed interface {
	~int | ~int8 | ~int16 | ~int32 | ~int64
}

type Summary

type Summary interface {
	// Summary Returns a short summary of the implementer.
	Summary() string
}

type SummaryWriter

type SummaryWriter interface {
	// WriteSummary Writes the Summary() string to the writer instead of being allocated as value.
	WriteSummary(w LineWriter)
}

type TestingJSONLogger added in v0.1.10

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

func NewTestingJSONLogger added in v0.1.10

func NewTestingJSONLogger() *TestingJSONLogger

NewTestingJSONLogger returns a very basic logger for testing purposes.

func (*TestingJSONLogger) Bytes added in v0.1.10

func (t *TestingJSONLogger) Bytes() []byte

Bytes returns the accumulated bytes.

func (*TestingJSONLogger) Log added in v0.1.10

func (t *TestingJSONLogger) Log(ctx context.Context, entry Entry)

Log implements tower.Logger.

func (*TestingJSONLogger) LogError added in v0.1.10

func (t *TestingJSONLogger) LogError(ctx context.Context, err Error)

LogError implements tower.Logger.

func (*TestingJSONLogger) MarshalJSON added in v0.1.10

func (t *TestingJSONLogger) MarshalJSON() ([]byte, error)

func (*TestingJSONLogger) PrettyPrint added in v0.1.10

func (t *TestingJSONLogger) PrettyPrint()

func (*TestingJSONLogger) Reset added in v0.1.10

func (t *TestingJSONLogger) Reset()

Reset resets the buffer to be empty.

func (*TestingJSONLogger) String added in v0.1.10

func (t *TestingJSONLogger) String() string

String returns the accumulated bytes as string.

type TimeHint added in v0.1.1

type TimeHint interface {
	// Time returns the time of this type.
	Time() time.Time
}

type Tower

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

Tower is an instance of Tower.

func NewTower added in v0.1.1

func NewTower(service Service) *Tower

NewTower Creates New Tower Instance. Using Built in Generator Engines by default.

func (*Tower) Bail added in v0.1.1

func (t *Tower) Bail(msg string, args ...any) ErrorBuilder

Bail creates a new ErrorBuilder from simple messages.

If args is not empty, msg will be fed into fmt.Errorf along with the args. Otherwise, msg will be fed into `errors.New()`.

func (*Tower) BailFreeze added in v0.1.1

func (t *Tower) BailFreeze(msg string, args ...any) Error

BailFreeze creates new immutable Error from simple messages.

If args is not empty, msg will be fed into fmt.Errorf along with the args. Otherwise, msg will be fed into `errors.New()`.

func (Tower) GetLogger added in v0.1.1

func (t Tower) GetLogger() Logger

GetLogger Gets the underlying Logger.

func (Tower) GetMessengerByName added in v0.1.1

func (t Tower) GetMessengerByName(name string) Messenger

GetMessengerByName Gets the Messenger by name. Returns nil if not found.

func (Tower) GetMessengers added in v0.1.1

func (t Tower) GetMessengers() Messengers

GetMessengers Returns a CLONE of the registered messengers.

func (Tower) GetService added in v0.1.1

func (t Tower) GetService() Service

GetService Gets the service metadata that Tower is running under.

func (Tower) Log added in v0.1.1

func (t Tower) Log(ctx context.Context, entry Entry)

Log Implements tower.Logger interface. So The Tower instance itself may be used as Logger Engine.

func (Tower) LogError added in v0.1.1

func (t Tower) LogError(ctx context.Context, err Error)

LogError Implements tower.Logger interface. So The Tower instance itself may be used as Logger Engine.

func (Tower) Name added in v0.1.1

func (t Tower) Name() string

Name Implements tower.Messenger interface. So The Tower instance itself may be used as Messenger.

Returns the service registered in the format of "tower-service_name-service_type-service_environment".

func (*Tower) NewEntry added in v0.1.1

func (t *Tower) NewEntry(msg string, args ...any) EntryBuilder

NewEntry Creates a new EntryBuilder. The returned EntryBuilder may be appended with values.

func (Tower) Notify added in v0.1.1

func (t Tower) Notify(ctx context.Context, entry Entry, parameters ...MessageOption)

Notify Sends the Entry to Messengers.

func (Tower) NotifyError added in v0.1.1

func (t Tower) NotifyError(ctx context.Context, err Error, parameters ...MessageOption)

NotifyError Sends the Error to Messengers.

func (*Tower) RegisterMessenger added in v0.1.3

func (t *Tower) RegisterMessenger(messenger Messenger)

RegisterMessenger Registers a messenger to the tower.

The messenger's name should be unique. Same name will replace the previous messenger with the same name.

If you wish to have multiple messengers of the same type, you should use different names for each of them.

func (*Tower) RemoveMessenger added in v0.1.3

func (t *Tower) RemoveMessenger(name string)

RemoveMessenger Removes the Messenger by name.

func (Tower) SendMessage added in v0.1.1

func (t Tower) SendMessage(ctx context.Context, msg MessageContext)

SendMessage Implements tower.Messenger interface. So The Tower instance itself may be used as Messenger.

Sends notification to all messengers registered in this instance.

func (*Tower) SetCallerDepth added in v0.1.1

func (t *Tower) SetCallerDepth(callerDepth int)

SetCallerDepth Sets the depth of the caller to be used when constructing the ErrorBuilder.

func (*Tower) SetDefaultNotifyOption added in v0.1.1

func (t *Tower) SetDefaultNotifyOption(opts ...MessageOption)

SetDefaultNotifyOption Sets the default options for Notify and NotifyError. When Notify or NotifyError is called, the default options will be applied first, then followed by the options passed in on premise by the user.

func (*Tower) SetEntryConstructor added in v0.1.1

func (t *Tower) SetEntryConstructor(c EntryConstructor)

SetEntryConstructor Sets how the EntryBuilder will be constructed.

func (*Tower) SetErrorConstructor added in v0.1.1

func (t *Tower) SetErrorConstructor(c ErrorConstructor)

SetErrorConstructor Sets how the ErrorBuilder will be constructed.

func (*Tower) SetErrorMessageContextBuilder added in v0.1.1

func (t *Tower) SetErrorMessageContextBuilder(b ErrorMessageContextBuilder)

SetErrorMessageContextBuilder Sets how the MessageContext will be built from tower.Error.

func (*Tower) SetLogger added in v0.1.1

func (t *Tower) SetLogger(log Logger)

SetLogger Sets the underlying Logger. This method is NOT concurrent safe.

func (*Tower) SetMessageContextBuilder added in v0.1.1

func (t *Tower) SetMessageContextBuilder(b MessageContextBuilder)

SetMessageContextBuilder Sets how the MessageContext will be built from tower.Entry.

func (Tower) Wait added in v0.1.1

func (t Tower) Wait(ctx context.Context) error

Wait Implements tower.Messenger interface. So The Tower instance itself may be used as Messenger.

Waits until all message in the queue or until given channel is received.

Implementer must exit the function as soon as possible when this ctx is canceled.

func (*Tower) Wrap added in v0.1.1

func (t *Tower) Wrap(err error) ErrorBuilder

Wrap like exported tower.Wrap, but at the scope of this Tower's instance instead.

func (*Tower) WrapFreeze added in v0.1.1

func (t *Tower) WrapFreeze(err error, message string, args ...any) Error

WrapFreeze is a Shorthand for tower.Wrap(err).Message(message).Freeze()

Useful when just wanting to add extra simple messages to the error chain. If args is not empty, message will be fed into fmt.Errorf along with the args.

type Trace added in v0.1.1

type Trace []KeyValue[string, string]

type TraceCaptureFunc added in v0.1.1

type TraceCaptureFunc func(ctx context.Context) Trace

func (TraceCaptureFunc) CaptureTrace added in v0.1.1

func (t TraceCaptureFunc) CaptureTrace(ctx context.Context) Trace

type TraceCapturer added in v0.1.1

type TraceCapturer interface {
	CaptureTrace(ctx context.Context) Trace
}

type Unsigned added in v0.1.1

type Unsigned interface {
	~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
}

Directories

Path Synopsis
bucket module
minio Module
s3 Module
cache module
goredis Module
loader module
pool module
queue module
towerdiscord module
towerhttp module
towerslack module
towerzap module

Jump to

Keyboard shortcuts

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