mirror of
https://github.com/shadow1ng/fscan.git
synced 2026-09-23 19:51:52 +08:00
feat: add -debug flag with file logging to fscan_debug.log
This commit is contained in:
@@ -182,6 +182,7 @@ func Flag(Info *HostInfo) error {
|
||||
flag.BoolVar(&fv.Silent, "silent", false, i18n.GetText("flag_silent_mode"))
|
||||
flag.BoolVar(&fv.NoColor, "nocolor", false, i18n.GetText("flag_no_color"))
|
||||
flag.StringVar(&fv.LogLevel, "log", LogLevelBaseInfoSuccess, i18n.GetText("flag_log_level"))
|
||||
flag.BoolVar(&fv.Debug, "debug", false, i18n.GetText("flag_debug"))
|
||||
flag.BoolVar(&fv.DisableProgress, "nopg", false, i18n.GetText("flag_disable_progress"))
|
||||
flag.BoolVar(&fv.PerfStats, "perf", false, "输出性能统计JSON")
|
||||
|
||||
@@ -285,6 +286,11 @@ func shouldShowHelp(Info *HostInfo, fv *FlagVars) bool {
|
||||
func checkParameterConflicts() error {
|
||||
fv := flagVars
|
||||
|
||||
// -debug 等价于 -log debug
|
||||
if fv.Debug {
|
||||
fv.LogLevel = LogLevelDebug
|
||||
}
|
||||
|
||||
// 检查 -ao 和 -m icmp 同时指定的情况(向后兼容提示)
|
||||
if fv.AliveOnly && fv.ScanMode == "icmp" {
|
||||
LogInfo(i18n.GetText("param_conflict_ao_icmp_both"))
|
||||
|
||||
@@ -95,6 +95,7 @@ type FlagVars struct {
|
||||
Silent bool
|
||||
NoColor bool
|
||||
LogLevel string
|
||||
Debug bool
|
||||
DisableProgress bool
|
||||
PerfStats bool
|
||||
Language string
|
||||
|
||||
@@ -30,6 +30,8 @@ flag_disable_ping:
|
||||
other: "Disable ping detection"
|
||||
flag_disable_tcp_probe:
|
||||
other: "Disable TCP supplementary probe"
|
||||
flag_debug:
|
||||
other: "Enable debug mode, write logs to fscan_debug.log"
|
||||
flag_alive_only:
|
||||
other: "Alive detection only"
|
||||
flag_username:
|
||||
|
||||
@@ -30,6 +30,8 @@ flag_disable_ping:
|
||||
other: "禁用ping探测"
|
||||
flag_disable_tcp_probe:
|
||||
other: "禁用TCP补充探测"
|
||||
flag_debug:
|
||||
other: "开启调试模式,日志写入fscan_debug.log"
|
||||
flag_alive_only:
|
||||
other: "仅进行存活探测"
|
||||
flag_username:
|
||||
|
||||
@@ -30,6 +30,9 @@ func getGlobalLogger() *logging.Logger {
|
||||
Silent: fv.Silent,
|
||||
StartTime: GetGlobalState().GetStartTime(),
|
||||
}
|
||||
if fv.Debug {
|
||||
config.DebugLogFile = "fscan_debug.log"
|
||||
}
|
||||
globalLogger = logging.NewLogger(config)
|
||||
globalLogger.SetCoordinatedOutput(LogWithProgress)
|
||||
})
|
||||
@@ -78,3 +81,10 @@ func LogVuln(result string) { getGlobalLogger().Vuln(result) }
|
||||
|
||||
// LogError 输出错误日志
|
||||
func LogError(errMsg string) { getGlobalLogger().Error(errMsg) }
|
||||
|
||||
// CloseLogger 关闭日志系统,释放文件资源
|
||||
func CloseLogger() {
|
||||
if globalLogger != nil {
|
||||
globalLogger.Close()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package logging
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -27,6 +28,7 @@ type LoggerConfig struct {
|
||||
Silent bool `json:"silent"`
|
||||
StartTime time.Time `json:"start_time"`
|
||||
LevelColors map[LogLevel]interface{} `json:"-"`
|
||||
DebugLogFile string `json:"debug_log_file"`
|
||||
}
|
||||
|
||||
// DefaultLoggerConfig 默认日志器配置
|
||||
@@ -48,6 +50,7 @@ type Logger struct {
|
||||
startTime time.Time
|
||||
coordinatedOutput func(string)
|
||||
initialized bool
|
||||
debugFile *os.File
|
||||
}
|
||||
|
||||
// NewLogger 创建新的日志管理器
|
||||
@@ -56,11 +59,20 @@ func NewLogger(config *LoggerConfig) *Logger {
|
||||
config = DefaultLoggerConfig()
|
||||
}
|
||||
|
||||
return &Logger{
|
||||
l := &Logger{
|
||||
config: config,
|
||||
startTime: config.StartTime,
|
||||
initialized: true,
|
||||
}
|
||||
|
||||
if config.DebugLogFile != "" {
|
||||
f, err := os.OpenFile(config.DebugLogFile, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
|
||||
if err == nil {
|
||||
l.debugFile = f
|
||||
}
|
||||
}
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
// Initialize 初始化日志器
|
||||
@@ -139,12 +151,37 @@ func (l *Logger) log(level LogLevel, content string) {
|
||||
l.outputMessage(level, logMsg)
|
||||
}
|
||||
|
||||
// 写入debug日志文件(纯文本,无颜色)
|
||||
if l.debugFile != nil {
|
||||
timestamp := time.Since(l.startTime).Truncate(time.Millisecond)
|
||||
if strings.Contains(content, "\n") {
|
||||
lines := strings.Split(content, "\n")
|
||||
for _, line := range lines {
|
||||
if line != "" {
|
||||
fmt.Fprintf(l.debugFile, "[%s] %s %s\n", timestamp, prefix, line)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
fmt.Fprintf(l.debugFile, "[%s] %s %s\n", timestamp, prefix, content)
|
||||
}
|
||||
}
|
||||
|
||||
// 根据慢速输出设置决定是否添加延迟
|
||||
if l.config.SlowOutput {
|
||||
time.Sleep(SlowOutputDelay)
|
||||
}
|
||||
}
|
||||
|
||||
// Close 关闭日志器,释放文件资源
|
||||
func (l *Logger) Close() {
|
||||
l.mu.Lock()
|
||||
defer l.mu.Unlock()
|
||||
if l.debugFile != nil {
|
||||
_ = l.debugFile.Close()
|
||||
l.debugFile = nil
|
||||
}
|
||||
}
|
||||
|
||||
// shouldLog 检查是否应该记录该级别的日志
|
||||
// 层级过滤:消息级别 >= 配置级别 时显示,Error 始终显示
|
||||
func (l *Logger) shouldLog(level LogLevel) bool {
|
||||
|
||||
Reference in New Issue
Block a user