log-level flag and debug/info/warn/error value supports and apply
This commit is contained in:
parent
6551e8e854
commit
95bcc92f11
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/lionsoul2014/ip2region/maker/golang/xdb"
|
"github.com/lionsoul2014/ip2region/maker/golang/xdb"
|
||||||
"log"
|
"log"
|
||||||
|
"log/slog"
|
||||||
"os"
|
"os"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
@ -50,9 +51,33 @@ func iterateFlags(cb func(key string, val string) error) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func applyLogLevel(logLevel string) error {
|
||||||
|
// check and apply the log level
|
||||||
|
var levelLog = slog.LevelInfo
|
||||||
|
switch strings.ToLower(logLevel) {
|
||||||
|
case "debug":
|
||||||
|
levelLog = slog.LevelDebug
|
||||||
|
case "info":
|
||||||
|
levelLog = slog.LevelInfo
|
||||||
|
case "warn":
|
||||||
|
levelLog = slog.LevelWarn
|
||||||
|
case "error":
|
||||||
|
levelLog = slog.LevelError
|
||||||
|
case "":
|
||||||
|
// ignore the empty value
|
||||||
|
// and default it to LevelInfo
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("invalid log level %s", logLevel)
|
||||||
|
}
|
||||||
|
|
||||||
|
slog.SetLogLoggerLevel(levelLog)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func genDb() {
|
func genDb() {
|
||||||
var err error
|
var err error
|
||||||
var srcFile, dstFile = "", ""
|
var srcFile, dstFile = "", ""
|
||||||
|
var fieldList, logLevel = "", ""
|
||||||
var indexPolicy = xdb.VectorIndexPolicy
|
var indexPolicy = xdb.VectorIndexPolicy
|
||||||
var fErr = iterateFlags(func(key string, val string) error {
|
var fErr = iterateFlags(func(key string, val string) error {
|
||||||
switch key {
|
switch key {
|
||||||
|
|
@ -60,6 +85,10 @@ func genDb() {
|
||||||
srcFile = val
|
srcFile = val
|
||||||
case "dst":
|
case "dst":
|
||||||
dstFile = val
|
dstFile = val
|
||||||
|
case "log-level":
|
||||||
|
logLevel = val
|
||||||
|
case "field-list":
|
||||||
|
fieldList = val
|
||||||
case "index":
|
case "index":
|
||||||
indexPolicy, err = xdb.IndexPolicyFromString(val)
|
indexPolicy, err = xdb.IndexPolicyFromString(val)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -79,11 +108,22 @@ func genDb() {
|
||||||
if srcFile == "" || dstFile == "" {
|
if srcFile == "" || dstFile == "" {
|
||||||
fmt.Printf("%s gen [command options]\n", os.Args[0])
|
fmt.Printf("%s gen [command options]\n", os.Args[0])
|
||||||
fmt.Printf("options:\n")
|
fmt.Printf("options:\n")
|
||||||
fmt.Printf(" --src string source ip text file path\n")
|
fmt.Printf(" --src string source ip text file path\n")
|
||||||
fmt.Printf(" --dst string destination binary xdb file path\n")
|
fmt.Printf(" --dst string destination binary xdb file path\n")
|
||||||
|
fmt.Printf(" --field-list string field index list imploded with ',' eg: 0,1,2,3-6,7\n")
|
||||||
|
fmt.Printf(" --log-level string set the log level, options: debug/info/warn/error\n")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check and apply the log level
|
||||||
|
err = applyLogLevel(logLevel)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("failed to apply log level", "error", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
slog.Info("field-list", "value", fieldList)
|
||||||
|
|
||||||
// make the binary file
|
// make the binary file
|
||||||
tStart := time.Now()
|
tStart := time.Now()
|
||||||
maker, err := xdb.NewMaker(indexPolicy, srcFile, dstFile)
|
maker, err := xdb.NewMaker(indexPolicy, srcFile, dstFile)
|
||||||
|
|
@ -109,7 +149,7 @@ func genDb() {
|
||||||
fmt.Printf("failed End: %s\n", err)
|
fmt.Printf("failed End: %s\n", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("Done, elapsed: %s\n", time.Since(tStart))
|
slog.Info("make done", "elapsed", time.Since(tStart))
|
||||||
}
|
}
|
||||||
|
|
||||||
func testSearch() {
|
func testSearch() {
|
||||||
|
|
@ -154,7 +194,8 @@ quit : exit the test program`)
|
||||||
fmt.Print("ip2region>> ")
|
fmt.Print("ip2region>> ")
|
||||||
str, err := reader.ReadString('\n')
|
str, err := reader.ReadString('\n')
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("failed to read string: %s", err)
|
slog.Error("failed to read string", "error", err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
line := strings.TrimSpace(strings.TrimSuffix(str, "\n"))
|
line := strings.TrimSpace(strings.TrimSuffix(str, "\n"))
|
||||||
|
|
@ -166,7 +207,8 @@ quit : exit the test program`)
|
||||||
if line == "loadIndex" {
|
if line == "loadIndex" {
|
||||||
err = searcher.LoadVectorIndex()
|
err = searcher.LoadVectorIndex()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("failed to load vector index: %s", err)
|
slog.Error("failed to load vector index", "error", err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
fmt.Printf("vector index cached\n")
|
fmt.Printf("vector index cached\n")
|
||||||
continue
|
continue
|
||||||
|
|
@ -196,7 +238,7 @@ quit : exit the test program`)
|
||||||
|
|
||||||
func testBench() {
|
func testBench() {
|
||||||
var err error
|
var err error
|
||||||
var dbFile, srcFile = "", ""
|
var dbFile, srcFile, logLevel = "", "", ""
|
||||||
var ignoreError = false
|
var ignoreError = false
|
||||||
var fErr = iterateFlags(func(key string, val string) error {
|
var fErr = iterateFlags(func(key string, val string) error {
|
||||||
switch key {
|
switch key {
|
||||||
|
|
@ -204,6 +246,8 @@ func testBench() {
|
||||||
dbFile = val
|
dbFile = val
|
||||||
case "src":
|
case "src":
|
||||||
srcFile = val
|
srcFile = val
|
||||||
|
case "log-level":
|
||||||
|
logLevel = val
|
||||||
case "ignore-error":
|
case "ignore-error":
|
||||||
if val == "true" || val == "1" {
|
if val == "true" || val == "1" {
|
||||||
ignoreError = true
|
ignoreError = true
|
||||||
|
|
@ -227,10 +271,18 @@ func testBench() {
|
||||||
fmt.Printf("options:\n")
|
fmt.Printf("options:\n")
|
||||||
fmt.Printf(" --db string ip2region binary xdb file path\n")
|
fmt.Printf(" --db string ip2region binary xdb file path\n")
|
||||||
fmt.Printf(" --src string source ip text file path\n")
|
fmt.Printf(" --src string source ip text file path\n")
|
||||||
|
fmt.Printf(" --log-level string set the log level, options: debug/info/warn/error\n")
|
||||||
fmt.Printf(" --ignore-error bool keep going if bench failed\n")
|
fmt.Printf(" --ignore-error bool keep going if bench failed\n")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check and apply the log level
|
||||||
|
err = applyLogLevel(logLevel)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("failed to apply log level", "error", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
searcher, err := xdb.NewSearcher(dbFile)
|
searcher, err := xdb.NewSearcher(dbFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("failed to create searcher with `%s`: %s\n", dbFile, err)
|
fmt.Printf("failed to create searcher with `%s`: %s\n", dbFile, err)
|
||||||
|
|
@ -247,12 +299,13 @@ func testBench() {
|
||||||
}
|
}
|
||||||
|
|
||||||
var count, errCount, tStart = 0, 0, time.Now()
|
var count, errCount, tStart = 0, 0, time.Now()
|
||||||
|
slog.Info("Bench start", "xdbPath", dbFile, "srcPath", srcFile)
|
||||||
var iErr = xdb.IterateSegments(handle, nil, func(seg *xdb.Segment) error {
|
var iErr = xdb.IterateSegments(handle, nil, func(seg *xdb.Segment) error {
|
||||||
var l = fmt.Sprintf("%d|%d|%s", seg.StartIP, seg.EndIP, seg.Region)
|
var l = fmt.Sprintf("%d|%d|%s", seg.StartIP, seg.EndIP, seg.Region)
|
||||||
fmt.Printf("try to bench segment: `%s`\n", l)
|
slog.Debug("try to bench", "segment", l)
|
||||||
mip := xdb.MidIP(seg.StartIP, seg.EndIP)
|
mip := xdb.MidIP(seg.StartIP, seg.EndIP)
|
||||||
for _, ip := range []uint32{seg.StartIP, xdb.MidIP(seg.EndIP, mip), mip, xdb.MidIP(mip, seg.EndIP), seg.EndIP} {
|
for _, ip := range []uint32{seg.StartIP, xdb.MidIP(seg.EndIP, mip), mip, xdb.MidIP(mip, seg.EndIP), seg.EndIP} {
|
||||||
fmt.Printf("|-try to bench ip '%s' ... ", xdb.Long2IP(ip))
|
slog.Debug("|-try to bench", "ip", xdb.Long2IP(ip))
|
||||||
r, _, err := searcher.Search(ip)
|
r, _, err := searcher.Search(ip)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to search ip '%s': %s\n", xdb.Long2IP(ip), err)
|
return fmt.Errorf("failed to search ip '%s': %s\n", xdb.Long2IP(ip), err)
|
||||||
|
|
@ -262,12 +315,12 @@ func testBench() {
|
||||||
count++
|
count++
|
||||||
if r != seg.Region {
|
if r != seg.Region {
|
||||||
errCount++
|
errCount++
|
||||||
fmt.Printf(" --[Failed] (%s != %s)\n", r, seg.Region)
|
slog.Error(" --[Failed] region not match", "src", r, "dst", seg.Region)
|
||||||
if ignoreError == false {
|
if ignoreError == false {
|
||||||
return fmt.Errorf("")
|
return fmt.Errorf("")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf(" --[Ok]\n")
|
slog.Debug(" --[Ok]")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -277,7 +330,7 @@ func testBench() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("Bench finished, {count: %d, failed: %d, took: %s}\n", count, errCount, time.Since(tStart))
|
slog.Info("Bench finished", "count", count, "failed", errCount, "elapsed", time.Since(tStart))
|
||||||
}
|
}
|
||||||
|
|
||||||
func edit() {
|
func edit() {
|
||||||
|
|
@ -416,7 +469,6 @@ func main() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the log flag
|
|
||||||
log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
|
log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
|
||||||
switch strings.ToLower(os.Args[1]) {
|
switch strings.ToLower(os.Args[1]) {
|
||||||
case "gen":
|
case "gen":
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ package xdb
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log/slog"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
@ -100,7 +100,7 @@ func NewMaker(policy IndexPolicy, srcFile string, dstFile string) (*Maker, error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Maker) initDbHeader() error {
|
func (m *Maker) initDbHeader() error {
|
||||||
log.Printf("try to init the db header ... ")
|
slog.Info("try to init the db header ... ")
|
||||||
|
|
||||||
_, err := m.dstHandle.Seek(0, 0)
|
_, err := m.dstHandle.Seek(0, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -134,12 +134,12 @@ func (m *Maker) initDbHeader() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Maker) loadSegments() error {
|
func (m *Maker) loadSegments() error {
|
||||||
log.Printf("try to load the segments ... ")
|
slog.Info("try to load the segments ... ")
|
||||||
var last *Segment = nil
|
var last *Segment = nil
|
||||||
var tStart = time.Now()
|
var tStart = time.Now()
|
||||||
|
|
||||||
var iErr = IterateSegments(m.srcHandle, func(l string) {
|
var iErr = IterateSegments(m.srcHandle, func(l string) {
|
||||||
log.Printf("load segment: `%s`", l)
|
slog.Debug("loaded", "segment", l)
|
||||||
}, func(seg *Segment) error {
|
}, func(seg *Segment) error {
|
||||||
// check the continuity of the data segment
|
// check the continuity of the data segment
|
||||||
if err := seg.AfterCheck(last); err != nil {
|
if err := seg.AfterCheck(last); err != nil {
|
||||||
|
|
@ -154,7 +154,7 @@ func (m *Maker) loadSegments() error {
|
||||||
return fmt.Errorf("failed to load segments: %s", iErr)
|
return fmt.Errorf("failed to load segments: %s", iErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("all segments loaded, length: %d, elapsed: %s", len(m.segments), time.Since(tStart))
|
slog.Info("all segments loaded", "length", len(m.segments), "elapsed", time.Since(tStart))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -201,12 +201,12 @@ func (m *Maker) Start() error {
|
||||||
return fmt.Errorf("seek to data first ptr: %w", err)
|
return fmt.Errorf("seek to data first ptr: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("try to write the data block ... ")
|
slog.Info("try to write the data block ... ")
|
||||||
for _, seg := range m.segments {
|
for _, seg := range m.segments {
|
||||||
log.Printf("try to write region '%s' ... ", seg.Region)
|
slog.Debug("try to write", "region", seg.Region)
|
||||||
ptr, has := m.regionPool[seg.Region]
|
ptr, has := m.regionPool[seg.Region]
|
||||||
if has {
|
if has {
|
||||||
log.Printf(" --[Cached] with ptr=%d", ptr)
|
slog.Debug(" --[Cached]", "ptr=", ptr)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -227,11 +227,11 @@ func (m *Maker) Start() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
m.regionPool[seg.Region] = uint32(pos)
|
m.regionPool[seg.Region] = uint32(pos)
|
||||||
log.Printf(" --[Added] with ptr=%d", pos)
|
slog.Debug(" --[Added] with", "ptr", pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2, write the index block and cache the super index block
|
// 2, write the index block and cache the super index block
|
||||||
log.Printf("try to write the segment index block ... ")
|
slog.Info("try to write the segment index block ... ")
|
||||||
var indexBuff = make([]byte, SegmentIndexSize)
|
var indexBuff = make([]byte, SegmentIndexSize)
|
||||||
var counter, startIndexPtr, endIndexPtr = 0, int64(-1), int64(-1)
|
var counter, startIndexPtr, endIndexPtr = 0, int64(-1), int64(-1)
|
||||||
for _, seg := range m.segments {
|
for _, seg := range m.segments {
|
||||||
|
|
@ -249,7 +249,7 @@ func (m *Maker) Start() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
var segList = seg.Split()
|
var segList = seg.Split()
|
||||||
log.Printf("try to index segment(%d splits) %s ...", len(segList), seg.String())
|
slog.Debug("try to index segment", "length", len(segList), "splits", seg.String())
|
||||||
for _, s := range segList {
|
for _, s := range segList {
|
||||||
pos, err := m.dstHandle.Seek(0, 1)
|
pos, err := m.dstHandle.Seek(0, 1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -266,7 +266,7 @@ func (m *Maker) Start() error {
|
||||||
return fmt.Errorf("write segment index for '%s': %w", s.String(), err)
|
return fmt.Errorf("write segment index for '%s': %w", s.String(), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("|-segment index: %d, ptr: %d, segment: %s\n", counter, pos, s.String())
|
slog.Debug("|-segment index", "counter", counter, "ptr", pos, "segment", s.String())
|
||||||
m.setVectorIndex(s.StartIP, uint32(pos))
|
m.setVectorIndex(s.StartIP, uint32(pos))
|
||||||
counter++
|
counter++
|
||||||
|
|
||||||
|
|
@ -280,7 +280,7 @@ func (m *Maker) Start() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// synchronized the vector index block
|
// synchronized the vector index block
|
||||||
log.Printf("try to write the vector index block ... ")
|
slog.Info("try to write the vector index block ... ")
|
||||||
_, err = m.dstHandle.Seek(int64(HeaderInfoLength), 0)
|
_, err = m.dstHandle.Seek(int64(HeaderInfoLength), 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("seek vector index first ptr: %w", err)
|
return fmt.Errorf("seek vector index first ptr: %w", err)
|
||||||
|
|
@ -291,7 +291,7 @@ func (m *Maker) Start() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// synchronized the segment index info
|
// synchronized the segment index info
|
||||||
log.Printf("try to write the segment index ptr ... ")
|
slog.Info("try to write the segment index ptr ... ")
|
||||||
binary.LittleEndian.PutUint32(indexBuff, uint32(startIndexPtr))
|
binary.LittleEndian.PutUint32(indexBuff, uint32(startIndexPtr))
|
||||||
binary.LittleEndian.PutUint32(indexBuff[4:], uint32(endIndexPtr))
|
binary.LittleEndian.PutUint32(indexBuff[4:], uint32(endIndexPtr))
|
||||||
_, err = m.dstHandle.Seek(8, 0)
|
_, err = m.dstHandle.Seek(8, 0)
|
||||||
|
|
@ -304,8 +304,8 @@ func (m *Maker) Start() error {
|
||||||
return fmt.Errorf("write segment index ptr: %w", err)
|
return fmt.Errorf("write segment index ptr: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("write done, dataBlocks: %d, indexBlocks: (%d, %d), indexPtr: (%d, %d)",
|
slog.Info("write done", "dataBlocks", len(m.regionPool), "indexBlocks", len(m.segments),
|
||||||
len(m.regionPool), len(m.segments), counter, startIndexPtr, endIndexPtr)
|
"counter", counter, "startIndexPtr", startIndexPtr, "endIndexPtr", endIndexPtr)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue