mirror of
https://github.com/shadow1ng/fscan.git
synced 2026-09-26 21:21:53 +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.Silent, "silent", false, i18n.GetText("flag_silent_mode"))
|
||||||
flag.BoolVar(&fv.NoColor, "nocolor", false, i18n.GetText("flag_no_color"))
|
flag.BoolVar(&fv.NoColor, "nocolor", false, i18n.GetText("flag_no_color"))
|
||||||
flag.StringVar(&fv.LogLevel, "log", LogLevelBaseInfoSuccess, i18n.GetText("flag_log_level"))
|
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.DisableProgress, "nopg", false, i18n.GetText("flag_disable_progress"))
|
||||||
flag.BoolVar(&fv.PerfStats, "perf", false, "输出性能统计JSON")
|
flag.BoolVar(&fv.PerfStats, "perf", false, "输出性能统计JSON")
|
||||||
|
|
||||||
@@ -285,6 +286,11 @@ func shouldShowHelp(Info *HostInfo, fv *FlagVars) bool {
|
|||||||
func checkParameterConflicts() error {
|
func checkParameterConflicts() error {
|
||||||
fv := flagVars
|
fv := flagVars
|
||||||
|
|
||||||
|
// -debug 等价于 -log debug
|
||||||
|
if fv.Debug {
|
||||||
|
fv.LogLevel = LogLevelDebug
|
||||||
|
}
|
||||||
|
|
||||||
// 检查 -ao 和 -m icmp 同时指定的情况(向后兼容提示)
|
// 检查 -ao 和 -m icmp 同时指定的情况(向后兼容提示)
|
||||||
if fv.AliveOnly && fv.ScanMode == "icmp" {
|
if fv.AliveOnly && fv.ScanMode == "icmp" {
|
||||||
LogInfo(i18n.GetText("param_conflict_ao_icmp_both"))
|
LogInfo(i18n.GetText("param_conflict_ao_icmp_both"))
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ type FlagVars struct {
|
|||||||
Silent bool
|
Silent bool
|
||||||
NoColor bool
|
NoColor bool
|
||||||
LogLevel string
|
LogLevel string
|
||||||
|
Debug bool
|
||||||
DisableProgress bool
|
DisableProgress bool
|
||||||
PerfStats bool
|
PerfStats bool
|
||||||
Language string
|
Language string
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ flag_disable_ping:
|
|||||||
other: "Disable ping detection"
|
other: "Disable ping detection"
|
||||||
flag_disable_tcp_probe:
|
flag_disable_tcp_probe:
|
||||||
other: "Disable TCP supplementary probe"
|
other: "Disable TCP supplementary probe"
|
||||||
|
flag_debug:
|
||||||
|
other: "Enable debug mode, write logs to fscan_debug.log"
|
||||||
flag_alive_only:
|
flag_alive_only:
|
||||||
other: "Alive detection only"
|
other: "Alive detection only"
|
||||||
flag_username:
|
flag_username:
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ flag_disable_ping:
|
|||||||
other: "禁用ping探测"
|
other: "禁用ping探测"
|
||||||
flag_disable_tcp_probe:
|
flag_disable_tcp_probe:
|
||||||
other: "禁用TCP补充探测"
|
other: "禁用TCP补充探测"
|
||||||
|
flag_debug:
|
||||||
|
other: "开启调试模式,日志写入fscan_debug.log"
|
||||||
flag_alive_only:
|
flag_alive_only:
|
||||||
other: "仅进行存活探测"
|
other: "仅进行存活探测"
|
||||||
flag_username:
|
flag_username:
|
||||||
|
|||||||
@@ -30,6 +30,9 @@ func getGlobalLogger() *logging.Logger {
|
|||||||
Silent: fv.Silent,
|
Silent: fv.Silent,
|
||||||
StartTime: GetGlobalState().GetStartTime(),
|
StartTime: GetGlobalState().GetStartTime(),
|
||||||
}
|
}
|
||||||
|
if fv.Debug {
|
||||||
|
config.DebugLogFile = "fscan_debug.log"
|
||||||
|
}
|
||||||
globalLogger = logging.NewLogger(config)
|
globalLogger = logging.NewLogger(config)
|
||||||
globalLogger.SetCoordinatedOutput(LogWithProgress)
|
globalLogger.SetCoordinatedOutput(LogWithProgress)
|
||||||
})
|
})
|
||||||
@@ -78,3 +81,10 @@ func LogVuln(result string) { getGlobalLogger().Vuln(result) }
|
|||||||
|
|
||||||
// LogError 输出错误日志
|
// LogError 输出错误日志
|
||||||
func LogError(errMsg string) { getGlobalLogger().Error(errMsg) }
|
func LogError(errMsg string) { getGlobalLogger().Error(errMsg) }
|
||||||
|
|
||||||
|
// CloseLogger 关闭日志系统,释放文件资源
|
||||||
|
func CloseLogger() {
|
||||||
|
if globalLogger != nil {
|
||||||
|
globalLogger.Close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package logging
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@@ -27,6 +28,7 @@ type LoggerConfig struct {
|
|||||||
Silent bool `json:"silent"`
|
Silent bool `json:"silent"`
|
||||||
StartTime time.Time `json:"start_time"`
|
StartTime time.Time `json:"start_time"`
|
||||||
LevelColors map[LogLevel]interface{} `json:"-"`
|
LevelColors map[LogLevel]interface{} `json:"-"`
|
||||||
|
DebugLogFile string `json:"debug_log_file"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultLoggerConfig 默认日志器配置
|
// DefaultLoggerConfig 默认日志器配置
|
||||||
@@ -48,6 +50,7 @@ type Logger struct {
|
|||||||
startTime time.Time
|
startTime time.Time
|
||||||
coordinatedOutput func(string)
|
coordinatedOutput func(string)
|
||||||
initialized bool
|
initialized bool
|
||||||
|
debugFile *os.File
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewLogger 创建新的日志管理器
|
// NewLogger 创建新的日志管理器
|
||||||
@@ -56,11 +59,20 @@ func NewLogger(config *LoggerConfig) *Logger {
|
|||||||
config = DefaultLoggerConfig()
|
config = DefaultLoggerConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Logger{
|
l := &Logger{
|
||||||
config: config,
|
config: config,
|
||||||
startTime: config.StartTime,
|
startTime: config.StartTime,
|
||||||
initialized: true,
|
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 初始化日志器
|
// Initialize 初始化日志器
|
||||||
@@ -139,12 +151,37 @@ func (l *Logger) log(level LogLevel, content string) {
|
|||||||
l.outputMessage(level, logMsg)
|
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 {
|
if l.config.SlowOutput {
|
||||||
time.Sleep(SlowOutputDelay)
|
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 检查是否应该记录该级别的日志
|
// shouldLog 检查是否应该记录该级别的日志
|
||||||
// 层级过滤:消息级别 >= 配置级别 时显示,Error 始终显示
|
// 层级过滤:消息级别 >= 配置级别 时显示,Error 始终显示
|
||||||
func (l *Logger) shouldLog(level LogLevel) bool {
|
func (l *Logger) shouldLog(level LogLevel) bool {
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ func main() {
|
|||||||
os.Exit(130) // 128 + SIGINT(2) = 130,标准的中断退出码
|
os.Exit(130) // 128 + SIGINT(2) = 130,标准的中断退出码
|
||||||
}()
|
}()
|
||||||
defer func() { _ = common.Cleanup() }()
|
defer func() { _ = common.Cleanup() }()
|
||||||
|
defer common.CloseLogger()
|
||||||
|
|
||||||
// 执行扫描
|
// 执行扫描
|
||||||
core.RunScan(context.Background(), *result.Info, result.Session)
|
core.RunScan(context.Background(), *result.Info, result.Session)
|
||||||
|
|||||||
Reference in New Issue
Block a user