added basic logging package to be used from any sub packge
parent
626deecef2
commit
056205c356
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,111 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import sys
|
||||||
|
import shutil
|
||||||
|
from typing import Optional, List, Tuple, Dict
|
||||||
|
|
||||||
|
import typer
|
||||||
|
from rich import print
|
||||||
|
from rich.columns import Columns
|
||||||
|
from rich.console import Console
|
||||||
|
from rich.traceback import install
|
||||||
|
|
||||||
|
# fmt: off
|
||||||
|
# Mapping from topics to colors
|
||||||
|
TOPICS = {
|
||||||
|
"EXIT": "#9a9a99",
|
||||||
|
"STRT": "#67a0b2",
|
||||||
|
"PING": "#d0b343",
|
||||||
|
"SCAN": "#70c43f",
|
||||||
|
#"LOG1": "#4878bc",
|
||||||
|
#"LOG2": "#398280",
|
||||||
|
#"CMIT": "#98719f",
|
||||||
|
#"PERS": "#d08341",
|
||||||
|
#"SNAP": "#FD971F",
|
||||||
|
#"DROP": "#ff615c",
|
||||||
|
"CLNT": "#00813c",
|
||||||
|
#"TEST": "#fe2c79",
|
||||||
|
#"INFO": "#ffffff",
|
||||||
|
#"WARN": "#d08341",
|
||||||
|
"ERRO": "#fe2626",
|
||||||
|
}
|
||||||
|
# fmt: on
|
||||||
|
|
||||||
|
|
||||||
|
def list_topics(value: Optional[str]):
|
||||||
|
if value is None:
|
||||||
|
return value
|
||||||
|
topics = value.split(",")
|
||||||
|
for topic in topics:
|
||||||
|
if topic not in TOPICS:
|
||||||
|
raise typer.BadParameter(f"topic {topic} not recognized")
|
||||||
|
return topics
|
||||||
|
|
||||||
|
|
||||||
|
def main(
|
||||||
|
file: typer.FileText = typer.Argument(None, help="File to read, stdin otherwise"),
|
||||||
|
colorize: bool = typer.Option(True, "--no-color"),
|
||||||
|
n_columns: Optional[int] = typer.Option(None, "--columns", "-c"),
|
||||||
|
ignore: Optional[str] = typer.Option(None, "--ignore", "-i", callback=list_topics),
|
||||||
|
just: Optional[str] = typer.Option(None, "--just", "-j", callback=list_topics),
|
||||||
|
):
|
||||||
|
topics = list(TOPICS)
|
||||||
|
|
||||||
|
# We can take input from a stdin (pipes) or from a file
|
||||||
|
input_ = file if file else sys.stdin
|
||||||
|
# Print just some topics or exclude some topics (good for avoiding verbose ones)
|
||||||
|
if just:
|
||||||
|
topics = just
|
||||||
|
if ignore:
|
||||||
|
topics = [lvl for lvl in topics if lvl not in set(ignore)]
|
||||||
|
|
||||||
|
topics = set(topics)
|
||||||
|
console = Console()
|
||||||
|
width = console.size.width
|
||||||
|
|
||||||
|
panic = False
|
||||||
|
for line in input_:
|
||||||
|
try:
|
||||||
|
time, topic, *msg = line.strip().split(" ")
|
||||||
|
# To ignore some topics
|
||||||
|
if topic not in topics:
|
||||||
|
continue
|
||||||
|
|
||||||
|
msg = " ".join(msg)
|
||||||
|
|
||||||
|
# Debug calls from the test suite aren't associated with
|
||||||
|
# any particular peer. Otherwise we can treat second column
|
||||||
|
# as peer id
|
||||||
|
if topic != "TEST":
|
||||||
|
i = int(msg[1])
|
||||||
|
|
||||||
|
# Colorize output by using rich syntax when needed
|
||||||
|
if colorize and topic in TOPICS:
|
||||||
|
color = TOPICS[topic]
|
||||||
|
msg = f"[{color}]{msg}[/{color}]"
|
||||||
|
|
||||||
|
# Single column printing. Always the case for debug stmts in tests
|
||||||
|
if n_columns is None or topic == "TEST":
|
||||||
|
print(time, msg)
|
||||||
|
# Multi column printing, timing is dropped to maximize horizontal
|
||||||
|
# space. Heavylifting is done through rich.column.Columns object
|
||||||
|
else:
|
||||||
|
cols = ["" for _ in range(n_columns)]
|
||||||
|
msg = "" + msg
|
||||||
|
cols[i] = msg
|
||||||
|
col_width = int(width / n_columns)
|
||||||
|
cols = Columns(cols, width=col_width - 1, equal=True, expand=True)
|
||||||
|
print(cols)
|
||||||
|
except:
|
||||||
|
# Code from tests or panics does not follow format
|
||||||
|
# so we print it as is
|
||||||
|
if line.startswith("panic"):
|
||||||
|
panic = True
|
||||||
|
# Output from tests is usually important so add a
|
||||||
|
# horizontal line with hashes to make it more obvious
|
||||||
|
if not panic:
|
||||||
|
print("#" * console.width)
|
||||||
|
print(line, end="")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
typer.run(main)
|
@ -0,0 +1,63 @@
|
|||||||
|
package logging
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
func getVerbosity() int {
|
||||||
|
v := os.Getenv("VERBOSE")
|
||||||
|
level := 0
|
||||||
|
if v != "" {
|
||||||
|
var err error
|
||||||
|
level, err = strconv.Atoi(v)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Invalid Vverboity %v", v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return level
|
||||||
|
}
|
||||||
|
|
||||||
|
type logTopic string
|
||||||
|
const (
|
||||||
|
// define 4 character topic abbreviations for coloring
|
||||||
|
DError logTopic = "ERRO"
|
||||||
|
DClient logTopic = "CLNT"
|
||||||
|
DStart logTopic = "STRT"
|
||||||
|
DExit logTopic = "EXIT"
|
||||||
|
DPing logTopic = "PING"
|
||||||
|
DScan logTopic = "SCAN"
|
||||||
|
)
|
||||||
|
// the list can grow
|
||||||
|
|
||||||
|
var debugStart time.Time
|
||||||
|
var debugVerbosity int
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
filename := time.Now().Format("01-02T15:04:05")
|
||||||
|
filename += ".log"
|
||||||
|
f, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0664)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
log.SetOutput(f)
|
||||||
|
debugVerbosity = getVerbosity()
|
||||||
|
debugStart = time.Now()
|
||||||
|
|
||||||
|
log.SetFlags(log.Flags() &^ (log.Ldate | log.Ltime)) // turns off date and time so we can set manually
|
||||||
|
}
|
||||||
|
|
||||||
|
// example call Debug(dClient, "R%d connecting to client %d", r.Id, c.Id)
|
||||||
|
func Debug(topic logTopic, format string, a ...interface{}) {
|
||||||
|
if debugVerbosity >= 1 {
|
||||||
|
time := time.Since(debugStart).Microseconds()
|
||||||
|
time /= 100
|
||||||
|
prefix := fmt.Sprintf("%06d %v ", time, string(topic))
|
||||||
|
format = prefix + format
|
||||||
|
log.Printf(format, a...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue