Skip to content

Commit

Permalink
58 dockter 1 (#59)
Browse files Browse the repository at this point in the history
* #58 Renamed variables

* #58 Working system

* #58 Prepare for versioned release
  • Loading branch information
docktermj authored Jun 4, 2024
1 parent 1edc98f commit 81fc467
Show file tree
Hide file tree
Showing 7 changed files with 371 additions and 122 deletions.
6 changes: 3 additions & 3 deletions .testcoverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ local-prefix: "github.com/org/project"
threshold:
# (optional; default 0)
# The minimum coverage that each file should have
file: 85
file: 90

# (optional; default 0)
# The minimum coverage that each package should have
package: 85
package: 90

# (optional; default 0)
# The minimum total coverage project should have
total: 85
total: 90
# Holds regexp rules which will override thresholds for matched files or packages
# using their paths.
#
Expand Down
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

-

## [1.5.0] - 2024-06-04

### Added in 1.5.0

- Suport for `OptionMessageFields`

### Changed in 1.5.0

- From `Interface` to `Messenger`
- From `SimpleMessenger` to `BasicMessenger`

## [1.4.2] - 2024-05-31

### Changed in 1.4.2
Expand Down
8 changes: 6 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,18 @@ func main() {

// Example from README.md

aMessenger, _ := messenger.New()
optionMessageFields := &messenger.OptionMessageFields{
Value: []string{"id", "details"},
}

aMessenger, _ := messenger.New(optionMessageFields)
fmt.Printf("%s\n\n", aMessenger.NewJSON(0001, "Bob", "Mary"))
fmt.Println(aMessenger.NewSlog(1001, "Bob", "Mary"))
fmt.Println()

// Create a bare message generator.

messenger1, err := messenger.New()
messenger1, err := messenger.New(optionMessageFields)
testError(err, "Error: %s\n")

// Print some messages.
Expand Down
21 changes: 16 additions & 5 deletions messenger/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ import (
// Types - interface
// ----------------------------------------------------------------------------

// The Interface interface has methods for creating different
// The Messenger interface has methods for creating different
// representations of a message.
type Interface interface {
type Messenger interface {
NewJSON(messageNumber int, details ...interface{}) string
NewSlog(messageNumber int, details ...interface{}) (string, []interface{})
NewSlogLevel(messageNumber int, details ...interface{}) (string, slog.Level, []interface{})
Expand Down Expand Up @@ -106,6 +106,11 @@ type OptionIDStatuses struct {
Value map[int]string // Message number to status map
}

// List of fields included in final message.
type OptionMessageFields struct {
Value []string // One or more of AllMessageFields values.
}

// Format of the unique id.
type OptionMessageIDTemplate struct {
Value string // Format string.
Expand Down Expand Up @@ -199,6 +204,8 @@ var (
ErrEmptyStatuses = errors.New("statuses must be a map[int]string")
)

var AllMessageFields = []string{"details", "duration", "errors", "id", "level", "location", "status", "text", "time"}

// ----------------------------------------------------------------------------
// Public functions
// ----------------------------------------------------------------------------
Expand All @@ -207,9 +214,9 @@ var (
The New function creates a new instance of MessengerInterface.
Adding options can be used to modify subcomponents.
*/
func New(options ...interface{}) (Interface, error) {
func New(options ...interface{}) (Messenger, error) {
var err error
var result Interface
var result Messenger

// Default values.

Expand All @@ -219,6 +226,7 @@ func New(options ...interface{}) (Interface, error) {
idStatuses = map[int]string{}
componentIdentifier = 9999
messageIDTemplate = fmt.Sprintf("SZSDK%04d", componentIdentifier) + "%04d"
messageFields []string
)

// Process options.
Expand All @@ -227,6 +235,8 @@ func New(options ...interface{}) (Interface, error) {
switch typedValue := value.(type) {
case *OptionCallerSkip:
callerSkip = typedValue.Value
case *OptionMessageFields:
messageFields = typedValue.Value
case *OptionIDMessages:
idMessages = typedValue.Value
case *OptionIDStatuses:
Expand Down Expand Up @@ -255,10 +265,11 @@ func New(options ...interface{}) (Interface, error) {

// Create MessengerInterface.

result = &SimpleMessenger{
result = &BasicMessenger{
callerSkip: callerSkip,
idMessages: idMessages,
idStatuses: idStatuses,
messageFields: messageFields,
messageIDTemplate: messageIDTemplate,
}
return result, err
Expand Down
111 changes: 82 additions & 29 deletions messenger/messenger.go → messenger/messenger_basic.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ import (
"bytes"
"encoding/json"
"fmt"
"os"
"path/filepath"
"reflect"
"regexp"
"runtime"
"slices"
"sort"
"strings"
"time"
Expand All @@ -19,12 +21,13 @@ import (
// Types
// ----------------------------------------------------------------------------

// SimpleMessenger is an type-struct for an implementation of the MessengerInterface.
type SimpleMessenger struct {
// BasicMessenger is an type-struct for an implementation of the MessengerInterface.
type BasicMessenger struct {
callerSkip int // Levels of code nexting to skip when calculation location
idMessages map[int]string // Map message numbers to text format strings
idStatuses map[int]string
messageFields []string
messageIDTemplate string // A string template for fmt.Sprinf()
callerSkip int // Levels of code nexting to skip when calculation location
sortedIDLevelRanges []int // The keys of IdLevelRanges in sorted order.
}

Expand Down Expand Up @@ -160,7 +163,7 @@ func messageDetails(details ...interface{}) []Detail {

// Create a slice of ["key1", value1, "key2", value2, ...] which has oscillating
// key and values in the slice.
func (messenger *SimpleMessenger) getKeyValuePairs(appMessageFormat *MessageFormat, keys []string) []interface{} {
func (messenger *BasicMessenger) getKeyValuePairs(appMessageFormat *MessageFormat, keys []string) []interface{} {
var result []interface{}
keyValueMap := map[string]interface{}{
"time": appMessageFormat.Time,
Expand Down Expand Up @@ -199,7 +202,7 @@ func (messenger *SimpleMessenger) getKeyValuePairs(appMessageFormat *MessageForm
}

// Given a message number, figure out the Level (TRACE, DEBUG, ..., FATAL, PANIC)
func (messenger *SimpleMessenger) getLevel(messageNumber int) string {
func (messenger *BasicMessenger) getLevel(messageNumber int) string {
sortedMessageLevelKeys := messenger.getSortedIDLevelRanges(IDLevelRangesAsString)
for _, messageLevelKey := range sortedMessageLevelKeys {
if messageNumber >= messageLevelKey {
Expand All @@ -210,7 +213,7 @@ func (messenger *SimpleMessenger) getLevel(messageNumber int) string {
}

// Since a map[int]any is not guaranteed to be in order, return an ordered slice of int.
func (messenger *SimpleMessenger) getSortedIDLevelRanges(idLevelRanges map[int]string) []int {
func (messenger *BasicMessenger) getSortedIDLevelRanges(idLevelRanges map[int]string) []int {
if messenger.sortedIDLevelRanges == nil {
messenger.sortedIDLevelRanges = make([]int, 0, len(idLevelRanges))
for key := range idLevelRanges {
Expand All @@ -221,17 +224,37 @@ func (messenger *SimpleMessenger) getSortedIDLevelRanges(idLevelRanges map[int]s
return messenger.sortedIDLevelRanges
}

func (messenger *BasicMessenger) populateMessageFields() {
senzingMessageFields := strings.TrimSpace(strings.ToLower(os.Getenv("SENZING_MESSAGE_FIELDS")))
switch {
case len(senzingMessageFields) == 0:
messenger.messageFields = []string{"id", "text"}
case senzingMessageFields == "all":
messenger.messageFields = AllMessageFields
default:
messenger.messageFields = []string{}
messageSplits := strings.Split(senzingMessageFields, ",")
for _, value := range messageSplits {
valueTrimmed := strings.TrimSpace(value)
if slices.Contains(AllMessageFields, valueTrimmed) {
messenger.messageFields = append(messenger.messageFields, valueTrimmed)
}
}
}
}

// Create a populated MessageFormat.
func (messenger *SimpleMessenger) populateStructure(messageNumber int, details ...interface{}) *MessageFormat {
func (messenger *BasicMessenger) populateStructure(messageNumber int, details ...interface{}) *MessageFormat {

var (
callerSkip int
duration int64
errorList []interface{}
level string
location string
status string
text string
callerSkip int
duration int64
errorList []interface{}
level string
location string
messageFields []string
status string
text string
)

// Calculate fields.
Expand Down Expand Up @@ -283,6 +306,8 @@ func (messenger *SimpleMessenger) populateStructure(messageNumber int, details .
timeNow = typedValue.Value.Format(time.RFC3339Nano)
case *OptionCallerSkip:
callerSkip = typedValue.Value
case *OptionMessageFields:
messageFields = typedValue.Value
case error:
errorList = append(errorList, cleanErrorString(typedValue))
filteredDetails = append(filteredDetails, typedValue)
Expand Down Expand Up @@ -315,23 +340,51 @@ func (messenger *SimpleMessenger) populateStructure(messageNumber int, details .
}
}

// Determine fields to print.

if messageFields == nil {
if messenger.messageFields == nil {
messenger.populateMessageFields()
}
messageFields = messenger.messageFields
}

// Compose result.

result := &MessageFormat{
Time: timeNow,
Level: level,
ID: id,
Text: text,
Status: status,
Duration: duration,
Location: location,
result := &MessageFormat{}

if slices.Contains(messageFields, "details") {
if len(filteredDetails) > 0 {
result.Details = messageDetails(filteredDetails...)
}
}
if slices.Contains(messageFields, "duration") {
result.Duration = duration
}
if slices.Contains(messageFields, "errors") {
if len(errorList) > 0 {
result.Errors = errorList
}
}
if len(errorList) > 0 {
result.Errors = errorList
if slices.Contains(messageFields, "id") {
result.ID = id
}
if len(filteredDetails) > 0 {
result.Details = messageDetails(filteredDetails...)
if slices.Contains(messageFields, "level") {
result.Level = level
}
if slices.Contains(messageFields, "location") {
result.Location = location
}
if slices.Contains(messageFields, "status") {
result.Status = status
}
if slices.Contains(messageFields, "text") {
result.Text = text
}
if slices.Contains(messageFields, "time") {
result.Time = timeNow
}

return result
}

Expand All @@ -349,7 +402,7 @@ Input
Output
- A JSON string representing the details formatted by the template identified by the messageNumber.
*/
func (messenger *SimpleMessenger) NewJSON(messageNumber int, details ...interface{}) string {
func (messenger *BasicMessenger) NewJSON(messageNumber int, details ...interface{}) string {
messageFormat := messenger.populateStructure(messageNumber, details...)

// Construct return value.
Expand Down Expand Up @@ -383,7 +436,7 @@ Output
- A text message
- A slice of oscillating key-value pairs.
*/
func (messenger *SimpleMessenger) NewSlog(messageNumber int, details ...interface{}) (string, []interface{}) {
func (messenger *BasicMessenger) NewSlog(messageNumber int, details ...interface{}) (string, []interface{}) {
message, _, keyValuePairs := messenger.NewSlogLevel(messageNumber, details...)
return message, keyValuePairs
}
Expand All @@ -400,7 +453,7 @@ Output
- A message level
- A slice of oscillating key-value pairs.
*/
func (messenger *SimpleMessenger) NewSlogLevel(messageNumber int, details ...interface{}) (string, slog.Level, []interface{}) {
func (messenger *BasicMessenger) NewSlogLevel(messageNumber int, details ...interface{}) (string, slog.Level, []interface{}) {
messageFormat := messenger.populateStructure(messageNumber, details...)

// Create a text message.
Expand Down
18 changes: 9 additions & 9 deletions messenger/messenger_examples_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,32 @@ import (
// Examples for godoc documentation
// ----------------------------------------------------------------------------

func ExampleSimpleMessenger_NewJSON() {
func ExampleBasicMessenger_NewJSON() {
// For more information, visit https://github.com/senzing-garage/go-messaging/blob/main/messenger/messenger_examples_test.go
example, err := New()
if err != nil {
fmt.Println(err)
}
fmt.Print(example.NewJSON(2001, "Bob", "Jane", getTimestamp(), getOptionCallerSkip()))
//Output: {"time":"2000-01-01T00:00:00Z","level":"INFO","id":"SZSDK99992001","location":"In ExampleSimpleMessenger_NewJSON() at messenger_examples_test.go:17","details":[{"position":1,"type":"string","value":"Bob"},{"position":2,"type":"string","value":"Jane"}]}
fmt.Print(example.NewJSON(2001, "Bob", "Jane", getOptionMessageFields()))
//Output: {"level":"INFO","id":"SZSDK99992001","details":[{"position":1,"type":"string","value":"Bob"},{"position":2,"type":"string","value":"Jane"}]}
}

func ExampleSimpleMessenger_NewSlog() {
func ExampleBasicMessenger_NewSlog() {
// For more information, visit https://github.com/senzing-garage/go-messaging/blob/main/messenger/messenger_examples_test.go
example, err := New()
if err != nil {
fmt.Println(err)
}
fmt.Print(example.NewSlog(2001, "Bob", "Jane", getTimestamp(), getOptionCallerSkip()))
//Output: [id SZSDK99992001 location In NewSlog() at messenger.go:387 details [{ 1 string Bob <nil>} { 2 string Jane <nil>}]]
fmt.Print(example.NewSlog(2001, "Bob", "Jane", getOptionMessageFields()))
//Output: [id SZSDK99992001 details [{ 1 string Bob <nil>} { 2 string Jane <nil>}]]
}

func ExampleSimpleMessenger_NewSlogLevel() {
func ExampleBasicMessenger_NewSlogLevel() {
// For more information, visit https://github.com/senzing-garage/go-messaging/blob/main/messenger/messenger_examples_test.go
example, err := New()
if err != nil {
fmt.Println(err)
}
fmt.Print(example.NewSlogLevel(2001, "Bob", "Jane", getTimestamp(), getOptionCallerSkip()))
//Output: INFO [id SZSDK99992001 location In ExampleSimpleMessenger_NewSlogLevel() at messenger_examples_test.go:37 details [{ 1 string Bob <nil>} { 2 string Jane <nil>}]]
fmt.Print(example.NewSlogLevel(2001, "Bob", "Jane", getOptionMessageFields()))
//Output: INFO [id SZSDK99992001 details [{ 1 string Bob <nil>} { 2 string Jane <nil>}]]
}
Loading

0 comments on commit 81fc467

Please sign in to comment.