github.com/qlik-oss/gopherciser@v0.18.6/logger/regression.go (about)

     1  package logger
     2  
     3  import (
     4  	"github.com/goccy/go-json"
     5  	"fmt"
     6  	"io"
     7  	"strings"
     8  
     9  	"github.com/qlik-oss/gopherciser/version"
    10  )
    11  
    12  type (
    13  	// RegressionLogger logs data associated with unique ids, with optional
    14  	// meta data.
    15  	RegressionLogger interface {
    16  		Log(dataID string, data interface{}, meta map[string]interface{}) error
    17  	}
    18  
    19  	// RegressionLoggerCloser is a closable RegressionLogger, which is typically
    20  	// used when writing log to file.
    21  	RegressionLoggerCloser interface {
    22  		io.Closer
    23  		RegressionLogger
    24  	}
    25  
    26  	regressionLogger struct {
    27  		w io.WriteCloser
    28  	}
    29  
    30  	filterType string
    31  
    32  	// HeaderEntry contains a Key mapped to a regression log meta data Value.
    33  	HeaderEntry struct {
    34  		Key   string
    35  		Value string
    36  	}
    37  )
    38  
    39  var filters = marshalFilters(
    40  	"+qStateCounts",
    41  	"+qGrandTotalRow",
    42  	"+qDataPages",
    43  	"+qPivotDataPages",
    44  	"+qStackedDataPages",
    45  	"-qNum",
    46  	"-qInExtRow",
    47  )
    48  
    49  func marshalFilters(filters ...filterType) []byte {
    50  	rawJson, err := json.Marshal(filters)
    51  	if err != nil {
    52  		panic(err)
    53  	}
    54  	return rawJson
    55  }
    56  
    57  func (logger *regressionLogger) write(record ...string) {
    58  	for i, r := range record {
    59  		record[i] = replacer.Replace(r)
    60  	}
    61  	fmt.Fprintln(logger.w, strings.Join(record, "\t"))
    62  }
    63  
    64  // NewRegressionLogger creates a new RegressionLoggerCloser with headerEntries
    65  // written in the header of the log.
    66  func NewRegressionLogger(w io.WriteCloser, headerEntries ...HeaderEntry) RegressionLoggerCloser {
    67  	logger := &regressionLogger{w}
    68  	logger.write("HEADER_KEY", "HEADER_VALUE")
    69  	logger.write("FILTERS", string(filters))
    70  	logger.write("VERSION", version.Version)
    71  	for _, he := range headerEntries {
    72  		logger.write(strings.ToUpper(strings.TrimSpace(he.Key)), strings.TrimSpace(he.Value))
    73  	}
    74  	logger.write("---")
    75  	logger.write("ID", "META", "DATA")
    76  	return logger
    77  }
    78  
    79  // Close the io.WriteCloser used to create the regressionLogger
    80  func (logger *regressionLogger) Close() error {
    81  	return logger.w.Close()
    82  }
    83  
    84  // Log the regression analysis data associated with a unique id. Caller is
    85  // responsible for setting a unique id. Pass meta data to support interpretaton
    86  // of log and regression analysis results.
    87  func (logger *regressionLogger) Log(dataID string, data interface{}, meta map[string]interface{}) error {
    88  	dataIDJSON, err := json.Marshal(dataID)
    89  	if err != nil {
    90  		return err
    91  	}
    92  
    93  	dataJSON, err := json.Marshal(data)
    94  	if err != nil {
    95  		return err
    96  	}
    97  
    98  	metaJSON, err := json.Marshal(meta)
    99  	if err != nil {
   100  		return err
   101  	}
   102  
   103  	logger.write(string(dataIDJSON), string(metaJSON), string(dataJSON))
   104  	return nil
   105  }