From ec101fbc0f7b5d771638e54d083f2457fa6511c2 Mon Sep 17 00:00:00 2001 From: Toni Uhlig Date: Thu, 3 Sep 2020 20:34:57 +0200 Subject: go-dashboard: Print unmarshalled JSON string in a textbox. Signed-off-by: Toni Uhlig --- examples/go-dashboard/main.go | 199 ++++++++++++++++++++-------------- examples/go-dashboard/ui/ui.go | 59 +++++++--- examples/go-dashboard/vendor/ui/ui.go | 59 +++++++--- 3 files changed, 205 insertions(+), 112 deletions(-) diff --git a/examples/go-dashboard/main.go b/examples/go-dashboard/main.go index c3ae62b37..8201ca9df 100644 --- a/examples/go-dashboard/main.go +++ b/examples/go-dashboard/main.go @@ -3,6 +3,7 @@ package main import ( "bufio" "encoding/json" + "fmt" "io" "log" "net" @@ -64,112 +65,150 @@ type basic_event struct { BasicEventName string `json:"basic_event_name"` } -func main() { - ui.Init() - - InfoLogger = log.New(os.Stderr, "INFO: ", log.Ldate|log.Ltime|log.Lshortfile) - WarningLogger = log.New(os.Stderr, "WARNING: ", log.Ldate|log.Ltime|log.Lshortfile) - ErrorLogger = log.New(os.Stderr, "ERROR: ", log.Ldate|log.Ltime|log.Lshortfile) - - conn, err := net.Dial("tcp", "127.0.0.1:7000") +func processJson(jsonStr string) { + jsonMap := make(map[string]interface{}) + err := json.Unmarshal([]byte(jsonStr), &jsonMap) if err != nil { - ErrorLogger.Printf("Connection failed: %v\n", err) + ErrorLogger.Printf("BUG: JSON error: %v\n", err) os.Exit(1) } + if jsonMap["packet_event_id"] != nil { + pe := packet_event{} + if err := json.Unmarshal([]byte(jsonStr), &pe); err != nil { + ErrorLogger.Printf("BUG: JSON Unmarshal error: %v\n", err) + os.Exit(1) + } + InfoLogger.Printf("PACKET EVENT %v\n", pe) + } else if jsonMap["flow_event_id"] != nil { + fe := flow_event{} + if err := json.Unmarshal([]byte(jsonStr), &fe); err != nil { + ErrorLogger.Printf("BUG: JSON Unmarshal error: %v\n", err) + os.Exit(1) + } + InfoLogger.Printf("FLOW EVENT %v\n", fe) + } else if jsonMap["basic_event_id"] != nil { + be := basic_event{} + if err := json.Unmarshal([]byte(jsonStr), &be); err != nil { + ErrorLogger.Printf("BUG: JSON Unmarshal error: %v\n", err) + os.Exit(1) + } + InfoLogger.Printf("BASIC EVENT %v\n", be) + } else { + ErrorLogger.Printf("BUG: Unknown JSON: %v\n", jsonStr) + os.Exit(1) + } + //InfoLogger.Printf("JSON map: %v\n-------------------------------------------------------\n", jsonMap) +} - buf := make([]byte, NETWORK_BUFFER_MAX_SIZE) - var jsonStr string - var jsonStrLen uint16 = 0 - var jsonLen uint16 = 0 - - rd := bufio.NewReaderSize(conn, int(NETWORK_BUFFER_MAX_SIZE)) +func eventHandler(ui *ui.Tui, wdgts *ui.Widgets, reader chan string) { for { - nread, err := rd.Read(buf) + select { + case <-ui.MainTicker.C: + if err := wdgts.RawJson.Write(fmt.Sprintf("%s\n", "--- HEARTBEAT ---")); err != nil { + panic(err) + } - if err != nil { - if err != io.EOF { - ErrorLogger.Printf("Read Error: %v\n", err) - break + case <-ui.Context.Done(): + return + + case jsonStr := <-reader: + if err := wdgts.RawJson.Write(fmt.Sprintf("%s\n", jsonStr)); err != nil { + panic(err) } } + } +} + +func main() { + InfoLogger = log.New(os.Stderr, "INFO: ", log.Ldate|log.Ltime|log.Lshortfile) + WarningLogger = log.New(os.Stderr, "WARNING: ", log.Ldate|log.Ltime|log.Lshortfile) + ErrorLogger = log.New(os.Stderr, "ERROR: ", log.Ldate|log.Ltime|log.Lshortfile) + + writer := make(chan string, 256) - if nread == 0 || err == io.EOF { - WarningLogger.Printf("Disconnect from Server\n") - break + go func(writer chan string) { + con, err := net.Dial("tcp", "127.0.0.1:7000") + if err != nil { + ErrorLogger.Printf("Connection failed: %v\n", err) + os.Exit(1) } - jsonStr += string(buf[:nread]) - jsonStrLen += uint16(nread) + buf := make([]byte, NETWORK_BUFFER_MAX_SIZE) + jsonStr := string("") + jsonStrLen := uint16(0) + jsonLen := uint16(0) + brd := bufio.NewReaderSize(con, int(NETWORK_BUFFER_MAX_SIZE)) for { - if jsonStrLen < nDPIsrvd_JSON_BYTES+1 { - break - } - - if jsonStr[nDPIsrvd_JSON_BYTES] != '{' { - ErrorLogger.Printf("BUG: JSON invalid opening character at position %d: '%s' (%x)\n", - nDPIsrvd_JSON_BYTES, - string(jsonStr[:nDPIsrvd_JSON_BYTES]), jsonStr[nDPIsrvd_JSON_BYTES]) - os.Exit(1) - } + nread, err := brd.Read(buf) - if jsonLen == 0 { - var tmp uint64 - if tmp, err = strconv.ParseUint(strings.TrimLeft(jsonStr[:4], "0"), 10, 16); err != nil { - ErrorLogger.Printf("BUG: Could not parse length of a JSON string: %v\n", err) - os.Exit(1) - } else { - jsonLen = uint16(tmp) + if err != nil { + if err != io.EOF { + ErrorLogger.Printf("Read Error: %v\n", err) + break } } - if jsonStrLen < jsonLen+nDPIsrvd_JSON_BYTES { + if nread == 0 || err == io.EOF { + WarningLogger.Printf("Disconnect from Server\n") break } - if jsonStr[jsonLen+nDPIsrvd_JSON_BYTES-1] != '}' { - ErrorLogger.Printf("BUG: JSON invalid closing character at position %d: '%s'\n", - jsonLen+nDPIsrvd_JSON_BYTES, - string(jsonStr[jsonLen+nDPIsrvd_JSON_BYTES-1])) - os.Exit(1) - } + jsonStr += string(buf[:nread]) + jsonStrLen += uint16(nread) - jsonMap := make(map[string]interface{}) - err := json.Unmarshal([]byte(jsonStr[nDPIsrvd_JSON_BYTES:nDPIsrvd_JSON_BYTES+jsonLen]), &jsonMap) - if err != nil { - ErrorLogger.Printf("BUG: JSON error: %v\n", err) - os.Exit(1) - } - if jsonMap["packet_event_id"] != nil { - pe := packet_event{} - if err := json.Unmarshal([]byte(jsonStr[nDPIsrvd_JSON_BYTES:nDPIsrvd_JSON_BYTES+jsonLen]), &pe); err != nil { - ErrorLogger.Printf("BUG: JSON Unmarshal error: %v\n", err) - os.Exit(1) + for { + if jsonStrLen < nDPIsrvd_JSON_BYTES+1 { + break } - InfoLogger.Printf("PACKET EVENT %v\n", pe) - } else if jsonMap["flow_event_id"] != nil { - fe := flow_event{} - if err := json.Unmarshal([]byte(jsonStr[nDPIsrvd_JSON_BYTES:nDPIsrvd_JSON_BYTES+jsonLen]), &fe); err != nil { - ErrorLogger.Printf("BUG: JSON Unmarshal error: %v\n", err) + + if jsonStr[nDPIsrvd_JSON_BYTES] != '{' { + ErrorLogger.Printf("BUG: JSON invalid opening character at position %d: '%s' (%x)\n", + nDPIsrvd_JSON_BYTES, + string(jsonStr[:nDPIsrvd_JSON_BYTES]), jsonStr[nDPIsrvd_JSON_BYTES]) os.Exit(1) } - InfoLogger.Printf("FLOW EVENT %v\n", fe) - } else if jsonMap["basic_event_id"] != nil { - be := basic_event{} - if err := json.Unmarshal([]byte(jsonStr[nDPIsrvd_JSON_BYTES:nDPIsrvd_JSON_BYTES+jsonLen]), &be); err != nil { - ErrorLogger.Printf("BUG: JSON Unmarshal error: %v\n", err) + + if jsonLen == 0 { + var tmp uint64 + if tmp, err = strconv.ParseUint(strings.TrimLeft(jsonStr[:4], "0"), 10, 16); err != nil { + ErrorLogger.Printf("BUG: Could not parse length of a JSON string: %v\n", err) + os.Exit(1) + } else { + jsonLen = uint16(tmp) + } + } + + if jsonStrLen < jsonLen+nDPIsrvd_JSON_BYTES { + break + } + + if jsonStr[jsonLen+nDPIsrvd_JSON_BYTES-1] != '}' { + ErrorLogger.Printf("BUG: JSON invalid closing character at position %d: '%s'\n", + jsonLen+nDPIsrvd_JSON_BYTES, + string(jsonStr[jsonLen+nDPIsrvd_JSON_BYTES-1])) os.Exit(1) } - InfoLogger.Printf("BASIC EVENT %v\n", be) - } else { - ErrorLogger.Printf("BUG: Unknown JSON: %v\n", jsonStr[nDPIsrvd_JSON_BYTES:nDPIsrvd_JSON_BYTES+jsonLen]) - os.Exit(1) - } - //InfoLogger.Printf("JSON map: %v\n-------------------------------------------------------\n", jsonMap) - jsonStr = jsonStr[jsonLen+nDPIsrvd_JSON_BYTES:] - jsonStrLen -= (jsonLen + nDPIsrvd_JSON_BYTES) - jsonLen = 0 + writer <- jsonStr[nDPIsrvd_JSON_BYTES : nDPIsrvd_JSON_BYTES+jsonLen] + + jsonStr = jsonStr[jsonLen+nDPIsrvd_JSON_BYTES:] + jsonStrLen -= (jsonLen + nDPIsrvd_JSON_BYTES) + jsonLen = 0 + } } - } + }(writer) + + tui, wdgts := ui.Init() + go eventHandler(tui, wdgts, writer) + ui.Run(tui) + +/* + for { + select { + case _ = <-writer: + break + } + } +*/ } diff --git a/examples/go-dashboard/ui/ui.go b/examples/go-dashboard/ui/ui.go index e8c89f81d..8a42803dd 100644 --- a/examples/go-dashboard/ui/ui.go +++ b/examples/go-dashboard/ui/ui.go @@ -16,48 +16,66 @@ import ( const rootID = "root" const redrawInterval = 250 * time.Millisecond -type widgets struct { - menu *text.Text +type Tui struct { + Term terminalapi.Terminal + Context context.Context + Cancel context.CancelFunc + Container *container.Container + MainTicker *time.Ticker } -func newWidgets(ctx context.Context) (*widgets, error) { - menu, err := text.New(text.RollContent(), text.WrapAtWords()) +type Widgets struct { + Menu *text.Text + RawJson *text.Text +} + +func newWidgets(ctx context.Context) (*Widgets, error) { + menu, err := text.New() if err != nil { panic(err) } - return &widgets{ - menu: menu, + rawJson, err := text.New(text.RollContent(), text.WrapAtWords()) + if err != nil { + panic(err) + } + + return &Widgets{ + Menu: menu, + RawJson: rawJson, }, nil } -func Init() { - term, err := termbox.New(termbox.ColorMode(terminalapi.ColorMode256)) +func Init() (*Tui, *Widgets) { + var err error + + ui := Tui{} + ui.Term, err = termbox.New(termbox.ColorMode(terminalapi.ColorMode256)) if err != nil { panic(err) } - defer term.Close() - ctx, cancel := context.WithCancel(context.Background()) - wdgts, err := newWidgets(ctx) + ui.Context, ui.Cancel = context.WithCancel(context.Background()) + + wdgts, err := newWidgets(ui.Context) if err != nil { panic(err) } - cnt, err := container.New(term, + ui.Container, err = container.New(ui.Term, container.Border(linestyle.None), container.BorderTitle("[ESC to Quit]"), container.SplitHorizontal( container.Top( container.Border(linestyle.Light), container.BorderTitle("Go nDPId Dashboard"), - container.PlaceWidget(wdgts.menu), + container.PlaceWidget(wdgts.Menu), ), container.Bottom( container.Border(linestyle.Light), container.BorderTitle("Raw JSON"), - container.PlaceWidget(wdgts.menu), + container.PlaceWidget(wdgts.RawJson), ), container.SplitFixed(3), ), @@ -66,12 +84,21 @@ func Init() { panic(err) } + ui.MainTicker = time.NewTicker(1 * time.Second) + + return &ui, wdgts +} + +func Run(ui *Tui) { + defer ui.Term.Close() + quitter := func(k *terminalapi.Keyboard) { if k.Key == keyboard.KeyEsc || k.Key == keyboard.KeyCtrlC { - cancel() + ui.Cancel() } } - if err := termdash.Run(ctx, term, cnt, termdash.KeyboardSubscriber(quitter), termdash.RedrawInterval(redrawInterval)); err != nil { + + if err := termdash.Run(ui.Context, ui.Term, ui.Container, termdash.KeyboardSubscriber(quitter), termdash.RedrawInterval(redrawInterval)); err != nil { panic(err) } } diff --git a/examples/go-dashboard/vendor/ui/ui.go b/examples/go-dashboard/vendor/ui/ui.go index e8c89f81d..8a42803dd 100644 --- a/examples/go-dashboard/vendor/ui/ui.go +++ b/examples/go-dashboard/vendor/ui/ui.go @@ -16,48 +16,66 @@ import ( const rootID = "root" const redrawInterval = 250 * time.Millisecond -type widgets struct { - menu *text.Text +type Tui struct { + Term terminalapi.Terminal + Context context.Context + Cancel context.CancelFunc + Container *container.Container + MainTicker *time.Ticker } -func newWidgets(ctx context.Context) (*widgets, error) { - menu, err := text.New(text.RollContent(), text.WrapAtWords()) +type Widgets struct { + Menu *text.Text + RawJson *text.Text +} + +func newWidgets(ctx context.Context) (*Widgets, error) { + menu, err := text.New() if err != nil { panic(err) } - return &widgets{ - menu: menu, + rawJson, err := text.New(text.RollContent(), text.WrapAtWords()) + if err != nil { + panic(err) + } + + return &Widgets{ + Menu: menu, + RawJson: rawJson, }, nil } -func Init() { - term, err := termbox.New(termbox.ColorMode(terminalapi.ColorMode256)) +func Init() (*Tui, *Widgets) { + var err error + + ui := Tui{} + ui.Term, err = termbox.New(termbox.ColorMode(terminalapi.ColorMode256)) if err != nil { panic(err) } - defer term.Close() - ctx, cancel := context.WithCancel(context.Background()) - wdgts, err := newWidgets(ctx) + ui.Context, ui.Cancel = context.WithCancel(context.Background()) + + wdgts, err := newWidgets(ui.Context) if err != nil { panic(err) } - cnt, err := container.New(term, + ui.Container, err = container.New(ui.Term, container.Border(linestyle.None), container.BorderTitle("[ESC to Quit]"), container.SplitHorizontal( container.Top( container.Border(linestyle.Light), container.BorderTitle("Go nDPId Dashboard"), - container.PlaceWidget(wdgts.menu), + container.PlaceWidget(wdgts.Menu), ), container.Bottom( container.Border(linestyle.Light), container.BorderTitle("Raw JSON"), - container.PlaceWidget(wdgts.menu), + container.PlaceWidget(wdgts.RawJson), ), container.SplitFixed(3), ), @@ -66,12 +84,21 @@ func Init() { panic(err) } + ui.MainTicker = time.NewTicker(1 * time.Second) + + return &ui, wdgts +} + +func Run(ui *Tui) { + defer ui.Term.Close() + quitter := func(k *terminalapi.Keyboard) { if k.Key == keyboard.KeyEsc || k.Key == keyboard.KeyCtrlC { - cancel() + ui.Cancel() } } - if err := termdash.Run(ctx, term, cnt, termdash.KeyboardSubscriber(quitter), termdash.RedrawInterval(redrawInterval)); err != nil { + + if err := termdash.Run(ui.Context, ui.Term, ui.Container, termdash.KeyboardSubscriber(quitter), termdash.RedrawInterval(redrawInterval)); err != nil { panic(err) } } -- cgit v1.2.3