如何为JNativeHook创建日志文件以持久化键鼠数据?
入门实现路径(MacBook Pro)
一、解决JNativeHook数据覆盖问题,实现全量日志记录
1. 调整日志写入模式
默认JNativeHook的日志可能用了覆盖写入,你需要改成追加模式。用Java的FileWriter时,把第二个参数设为true,每次写入都会加到文件末尾,不会覆盖旧数据。
2. 监听并记录所有输入事件
给JNativeHook注册键盘、鼠标监听器,把事件的关键信息(按键类型、鼠标位置、时间戳)写入日志。下面是完整基础示例:
import org.jnativehook.GlobalScreen; import org.jnativehook.NativeHookException; import org.jnativehook.keyboard.NativeKeyEvent; import org.jnativehook.keyboard.NativeKeyListener; import org.jnativehook.mouse.NativeMouseEvent; import org.jnativehook.mouse.NativeMouseListener; import org.jnativehook.mouse.NativeMouseMotionListener; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; public class InputLogger implements NativeKeyListener, NativeMouseListener, NativeMouseMotionListener { private BufferedWriter writer; public InputLogger() { try { // 初始化追加模式的日志写入流 writer = new BufferedWriter(new FileWriter("input_logs.txt", true)); } catch (IOException e) { e.printStackTrace(); } } // 记录键盘按键按下事件 @Override public void nativeKeyPressed(NativeKeyEvent e) { logEvent("KEY_PRESSED", NativeKeyEvent.getKeyText(e.getKeyCode()), LocalDateTime.now()); } // 记录鼠标点击事件 @Override public void nativeMouseClicked(NativeMouseEvent e) { String clickType = switch (e.getButton()) { case NativeMouseEvent.BUTTON1 -> "LEFT_CLICK"; case NativeMouseEvent.BUTTON2 -> "MIDDLE_CLICK"; case NativeMouseEvent.BUTTON3 -> "RIGHT_CLICK"; default -> "UNKNOWN_CLICK"; }; logEvent("MOUSE_CLICK", clickType + " at (" + e.getX() + "," + e.getY() + ")", LocalDateTime.now()); } // 记录鼠标移动事件(可选,取消注释启用,会生成大量日志) @Override public void nativeMouseMoved(NativeMouseEvent e) { // logEvent("MOUSE_MOVE", "Position (" + e.getX() + "," + e.getY() + ")", LocalDateTime.now()); } // 通用日志写入方法 private void logEvent(String eventType, String details, LocalDateTime timestamp) { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"); String logLine = timestamp.format(formatter) + " | " + eventType + " | " + details + "\n"; try { writer.write(logLine); writer.flush(); // 实时写入文件,避免程序崩溃丢失数据 } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) { try { GlobalScreen.registerNativeHook(); } catch (NativeHookException ex) { System.err.println("无法注册全局钩子"); System.err.println(ex.getMessage()); System.exit(1); } InputLogger logger = new InputLogger(); GlobalScreen.addNativeKeyListener(logger); GlobalScreen.addNativeMouseListener(logger); GlobalScreen.addNativeMouseMotionListener(logger); } }
3. 处理Mac权限问题
新款Mac需要给程序授权输入监控权限:
- 打开「系统设置」→「隐私与安全性」→「输入监控」
- 找到你的Java应用或IDE(比如IntelliJ/Eclipse),勾选权限
- 重启程序生效
二、日志数据导入可视化工具
日志文件input_logs.txt是结构化文本,可通过以下工具处理:
1. Excel/Numbers快速分析
- 直接打开日志文件,用「|」作为分隔符拆分列(时间、事件类型、详情)
- 插入柱状图、折线图,统计按键次数、鼠标点击频率等
2. Python+Matplotlib/Seaborn专业可视化
用Python读取日志并生成自定义图表(需先安装pandas和matplotlib):
import pandas as pd import matplotlib.pyplot as plt # 读取日志文件 df = pd.read_csv('input_logs.txt', sep='|', header=None, names=['timestamp', 'event_type', 'details']) # 清理列内空格 df['timestamp'] = df['timestamp'].str.strip() df['event_type'] = df['event_type'].str.strip() # 转换时间格式 df['timestamp'] = pd.to_datetime(df['timestamp'], format='%Y-%m-%d %H:%M:%S.%f') # 统计每小时输入事件数 df['hour'] = df['timestamp'].dt.hour hourly_counts = df.groupby('hour')['event_type'].count() # 绘制柱状图 plt.figure(figsize=(10,6)) hourly_counts.plot(kind='bar') plt.title('每小时输入活动次数') plt.xlabel('小时') plt.ylabel('事件数量') plt.show()
3. Tableau/Power BI交互式可视化
导入日志到Tableau或Power BI,拖拽生成交互式仪表盘:
- 按天/小时的活动趋势图
- 鼠标点击区域热力图
- 不同按键的使用频率对比
三、注意事项
- 日志会持续增大,建议按天生成日志文件(比如
input_logs_20240520.txt) - 不要记录敏感信息(比如密码,可在
nativeKeyPressed中过滤或模糊处理) - Mac休眠/锁屏时,全局钩子可能暂停,需测试后台运行稳定性
内容的提问来源于stack exchange,提问作者intaboo
相关产品推荐
相关产品推荐

