mirror of
https://github.com/DominicBreuker/pspy.git
synced 2025-12-21 03:34:50 +00:00
enable coloring by UIDs
This commit is contained in:
@@ -2,14 +2,20 @@ package logging
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"hash/fnv"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ColorNone = iota
|
ColorNone = iota
|
||||||
ColorRed
|
ColorRed
|
||||||
ColorGreen
|
ColorGreen
|
||||||
|
ColorYellow
|
||||||
|
ColorBlue
|
||||||
|
ColorPurple
|
||||||
|
ColorTeal
|
||||||
)
|
)
|
||||||
|
|
||||||
type Logger struct {
|
type Logger struct {
|
||||||
@@ -43,14 +49,15 @@ func (l *Logger) Errorf(debug bool, format string, v ...interface{}) {
|
|||||||
// Eventf writes an event with timestamp to stdout
|
// Eventf writes an event with timestamp to stdout
|
||||||
func (l *Logger) Eventf(color int, format string, v ...interface{}) {
|
func (l *Logger) Eventf(color int, format string, v ...interface{}) {
|
||||||
msg := fmt.Sprintf(format, v...)
|
msg := fmt.Sprintf(format, v...)
|
||||||
|
if color != ColorNone {
|
||||||
switch color {
|
msg = fmt.Sprintf("\x1b[%d;1m%s\x1b[0m", 30+color, msg)
|
||||||
case ColorRed:
|
|
||||||
msg = fmt.Sprintf("\x1b[31;1m%s\x1b[0m", msg)
|
|
||||||
case ColorGreen:
|
|
||||||
msg = fmt.Sprintf("\x1b[32;1m%s\x1b[0m", msg)
|
|
||||||
default:
|
|
||||||
}
|
}
|
||||||
|
|
||||||
l.eventLogger.Printf("%s", msg)
|
l.eventLogger.Printf("%s", msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetColorByUID(uid int) int {
|
||||||
|
h := fnv.New32a()
|
||||||
|
h.Write([]byte(strconv.Itoa(uid)))
|
||||||
|
return (int(h.Sum32()) % (ColorTeal)) + 1
|
||||||
|
}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ var logTests = []struct {
|
|||||||
func TestLogging(t *testing.T) {
|
func TestLogging(t *testing.T) {
|
||||||
for i, tt := range logTests {
|
for i, tt := range logTests {
|
||||||
actual := captureOutput(tt.logger, tt.test)
|
actual := captureOutput(tt.logger, tt.test)
|
||||||
|
log.Printf("OUT: %s", actual)
|
||||||
|
|
||||||
// check colors and remove afterwards
|
// check colors and remove afterwards
|
||||||
colors := ansiMatcher.FindAll(actual, 2)
|
colors := ansiMatcher.FindAll(actual, 2)
|
||||||
@@ -55,3 +56,46 @@ func captureOutput(logger *log.Logger, f func()) []byte {
|
|||||||
f()
|
f()
|
||||||
return buf.Bytes()
|
return buf.Bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGetColorByUID(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
uid int
|
||||||
|
color int
|
||||||
|
}{
|
||||||
|
{uid: 0, color: 4},
|
||||||
|
{uid: 1, color: 5},
|
||||||
|
{uid: 2, color: 2},
|
||||||
|
{uid: 3, color: 3},
|
||||||
|
{uid: 99999999999, color: 5},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
color := GetColorByUID(tt.uid)
|
||||||
|
if color != tt.color {
|
||||||
|
t.Errorf("GetColorByUID(%d)=%d but want %d", tt.uid, color, tt.color)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
minColor := 9999999
|
||||||
|
maxColor := -9999999
|
||||||
|
for i := 0; i < 1000; i++ {
|
||||||
|
color := GetColorByUID(i)
|
||||||
|
if color < 1 || color > ColorTeal {
|
||||||
|
t.Fatalf("GetColorByUID(%d)=%d but this is out of range [%d, %d]", i, color, ColorRed, ColorTeal)
|
||||||
|
}
|
||||||
|
|
||||||
|
if color < minColor {
|
||||||
|
minColor = color
|
||||||
|
}
|
||||||
|
if color > maxColor {
|
||||||
|
maxColor = color
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if minColor != 1 {
|
||||||
|
t.Errorf("GetColorByUID returned minimum color %d, not %d, on 1000 trials, which is extremely unlikely", minColor, 1)
|
||||||
|
}
|
||||||
|
if maxColor != ColorTeal {
|
||||||
|
t.Errorf("GetColorByUID returned maximum color %d, not %d, on 1000 trials, which is extremely unlikely", maxColor, ColorTeal)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ func Start(cfg *config.Config, b *Bindings, sigCh chan os.Signal) chan struct{}
|
|||||||
|
|
||||||
func printOutput(cfg *config.Config, b *Bindings, chans *chans) chan struct{} {
|
func printOutput(cfg *config.Config, b *Bindings, chans *chans) chan struct{} {
|
||||||
exit := make(chan struct{})
|
exit := make(chan struct{})
|
||||||
fsEventColor, psEventColor := getColors(cfg.Colored)
|
// fsEventColor, psEventColor := getColors(cfg.Colored)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
@@ -67,11 +67,15 @@ func printOutput(cfg *config.Config, b *Bindings, chans *chans) chan struct{} {
|
|||||||
exit <- struct{}{}
|
exit <- struct{}{}
|
||||||
case fe := <-chans.fsEventCh:
|
case fe := <-chans.fsEventCh:
|
||||||
if cfg.LogFS {
|
if cfg.LogFS {
|
||||||
b.Logger.Eventf(fsEventColor, "FS: %+v", fe)
|
b.Logger.Eventf(logging.ColorNone, "FS: %+v", fe)
|
||||||
}
|
}
|
||||||
case pe := <-chans.psEventCh:
|
case pe := <-chans.psEventCh:
|
||||||
if cfg.LogPS {
|
if cfg.LogPS {
|
||||||
b.Logger.Eventf(psEventColor, "CMD: %+v", pe)
|
color := logging.ColorNone
|
||||||
|
if cfg.Colored {
|
||||||
|
color = logging.GetColorByUID(pe.UID)
|
||||||
|
}
|
||||||
|
b.Logger.Eventf(color, "CMD: %+v", pe)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -79,17 +83,6 @@ func printOutput(cfg *config.Config, b *Bindings, chans *chans) chan struct{} {
|
|||||||
return exit
|
return exit
|
||||||
}
|
}
|
||||||
|
|
||||||
func getColors(colored bool) (fsEventColor int, psEventColor int) {
|
|
||||||
if colored {
|
|
||||||
fsEventColor = logging.ColorGreen
|
|
||||||
psEventColor = logging.ColorRed
|
|
||||||
} else {
|
|
||||||
fsEventColor = logging.ColorNone
|
|
||||||
psEventColor = logging.ColorNone
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func initFSW(fsw FSWatcher, rdirs, dirs []string, logger Logger) {
|
func initFSW(fsw FSWatcher, rdirs, dirs []string, logger Logger) {
|
||||||
errCh, doneCh := fsw.Init(rdirs, dirs)
|
errCh, doneCh := fsw.Init(rdirs, dirs)
|
||||||
for {
|
for {
|
||||||
|
|||||||
@@ -68,24 +68,6 @@ func TestStartPSS(t *testing.T) {
|
|||||||
expectMessage(t, l.Error, "ERROR: error during refresh")
|
expectMessage(t, l.Error, "ERROR: error during refresh")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetColors(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
colored bool
|
|
||||||
fsEventColor int
|
|
||||||
psEventColor int
|
|
||||||
}{
|
|
||||||
{colored: true, fsEventColor: logging.ColorGreen, psEventColor: logging.ColorRed},
|
|
||||||
{colored: false, fsEventColor: logging.ColorNone, psEventColor: logging.ColorNone},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tt := range tests {
|
|
||||||
c1, c2 := getColors(tt.colored)
|
|
||||||
if c1 != tt.fsEventColor || c2 != tt.psEventColor {
|
|
||||||
t.Errorf("Got wrong colors when colored=%t: expected %d, %d but got %d, %d", tt.colored, tt.fsEventColor, tt.psEventColor, c1, c2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStart(t *testing.T) {
|
func TestStart(t *testing.T) {
|
||||||
drainFor := 10 * time.Millisecond
|
drainFor := 10 * time.Millisecond
|
||||||
triggerEvery := 999 * time.Second
|
triggerEvery := 999 * time.Second
|
||||||
@@ -126,9 +108,9 @@ func TestStart(t *testing.T) {
|
|||||||
<-time.After(2 * drainFor)
|
<-time.After(2 * drainFor)
|
||||||
expectMessage(t, l.Info, "done")
|
expectMessage(t, l.Info, "done")
|
||||||
expectTrigger(t, pss.runTriggerCh) // pss receives triggers from fsw
|
expectTrigger(t, pss.runTriggerCh) // pss receives triggers from fsw
|
||||||
expectMessage(t, l.Event, fmt.Sprintf("%d CMD: UID=1000 PID=12345 | pss event", logging.ColorRed))
|
expectMessage(t, l.Event, fmt.Sprintf("%d CMD: UID=1000 PID=12345 | pss event", logging.ColorPurple))
|
||||||
expectMessage(t, l.Error, "ERROR: pss error")
|
expectMessage(t, l.Error, "ERROR: pss error")
|
||||||
expectMessage(t, l.Event, fmt.Sprintf("%d FS: fsw event", logging.ColorGreen))
|
expectMessage(t, l.Event, fmt.Sprintf("%d FS: fsw event", logging.ColorNone))
|
||||||
expectMessage(t, l.Error, "ERROR: fsw error")
|
expectMessage(t, l.Error, "ERROR: fsw error")
|
||||||
expectMessage(t, l.Info, "Exiting program... (interrupt)")
|
expectMessage(t, l.Info, "Exiting program... (interrupt)")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user