mclog-parser 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 IVANOLIO
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,115 @@
1
+ Metadata-Version: 2.4
2
+ Name: mclog-parser
3
+ Version: 0.1.0
4
+ Summary: Parse and analyze Minecraft server log files
5
+ License: MIT
6
+ Keywords: minecraft,log,parser,server,analysis
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Topic :: Games/Entertainment
10
+ Requires-Python: >=3.10
11
+ Description-Content-Type: text/markdown
12
+ License-File: LICENSE
13
+ Dynamic: license-file
14
+
15
+ # mclog-parser
16
+ Analyze Minecraft server logs instantly — turn raw log files into structured data.
17
+ # mclog-parser 🎮
18
+
19
+ **Analyze Minecraft server logs instantly — turn raw log files into structured data.**
20
+
21
+ ```bash
22
+ pip install mclog-parser
23
+ ```
24
+
25
+ ---
26
+
27
+ ## Why?
28
+
29
+ Every Minecraft server generates thousands of log lines. Finding crashes, tracking players, or spotting lag spikes means scrolling through walls of text manually.
30
+
31
+ `mclog-parser` does it in one line.
32
+
33
+ ---
34
+
35
+ ## Quickstart
36
+
37
+ ```python
38
+ from mclog_parser import LogParser
39
+
40
+ log = LogParser("latest.log")
41
+
42
+ log.summary() # full overview
43
+ log.crashes() # all errors & crashes
44
+ log.lag_spikes() # lag warnings
45
+ log.player_stats() # per-player stats
46
+ log.export_json() # save report as JSON
47
+ ```
48
+
49
+ ### Example Output
50
+
51
+ ```json
52
+ {
53
+ "unique_players": 3,
54
+ "total_sessions": 5,
55
+ "crash_count": 1,
56
+ "lag_spike_count": 2,
57
+ "top_players": [
58
+ { "player": "Ahmed99", "sessions": 2, "deaths": 1 }
59
+ ]
60
+ }
61
+ ```
62
+
63
+ ---
64
+
65
+ ## CLI
66
+
67
+ No Python needed — run directly from your terminal:
68
+
69
+ ```bash
70
+ mclog latest.log # summary
71
+ mclog latest.log --crashes # errors only
72
+ mclog latest.log --players # player stats table
73
+ mclog latest.log --player Ahmed99 # one player's sessions
74
+ mclog latest.log --export report.json # export to JSON
75
+ ```
76
+
77
+ ---
78
+
79
+ ## Supported Servers
80
+
81
+ | Server | Status |
82
+ |--------|--------|
83
+ | Paper | ✅ |
84
+ | Spigot | ✅ |
85
+ | Vanilla | ✅ |
86
+ | Fabric | ✅ |
87
+ | Forge | 🔜 |
88
+
89
+ ---
90
+
91
+ ## Install
92
+
93
+ ```bash
94
+ pip install mclog-parser
95
+ ```
96
+
97
+ Requires Python 3.10+
98
+
99
+ ---
100
+
101
+ ## Roadmap
102
+
103
+ - [x] Core parser (crashes, lag, sessions)
104
+ - [x] Player stats
105
+ - [x] JSON export
106
+ - [x] CLI
107
+ - [ ] Web dashboard
108
+ - [ ] Discord bot integration
109
+ - [ ] Real-time log watching
110
+
111
+ ---
112
+
113
+ ## License
114
+
115
+ MIT — free to use, modify, and distribute.
@@ -0,0 +1,101 @@
1
+ # mclog-parser
2
+ Analyze Minecraft server logs instantly — turn raw log files into structured data.
3
+ # mclog-parser 🎮
4
+
5
+ **Analyze Minecraft server logs instantly — turn raw log files into structured data.**
6
+
7
+ ```bash
8
+ pip install mclog-parser
9
+ ```
10
+
11
+ ---
12
+
13
+ ## Why?
14
+
15
+ Every Minecraft server generates thousands of log lines. Finding crashes, tracking players, or spotting lag spikes means scrolling through walls of text manually.
16
+
17
+ `mclog-parser` does it in one line.
18
+
19
+ ---
20
+
21
+ ## Quickstart
22
+
23
+ ```python
24
+ from mclog_parser import LogParser
25
+
26
+ log = LogParser("latest.log")
27
+
28
+ log.summary() # full overview
29
+ log.crashes() # all errors & crashes
30
+ log.lag_spikes() # lag warnings
31
+ log.player_stats() # per-player stats
32
+ log.export_json() # save report as JSON
33
+ ```
34
+
35
+ ### Example Output
36
+
37
+ ```json
38
+ {
39
+ "unique_players": 3,
40
+ "total_sessions": 5,
41
+ "crash_count": 1,
42
+ "lag_spike_count": 2,
43
+ "top_players": [
44
+ { "player": "Ahmed99", "sessions": 2, "deaths": 1 }
45
+ ]
46
+ }
47
+ ```
48
+
49
+ ---
50
+
51
+ ## CLI
52
+
53
+ No Python needed — run directly from your terminal:
54
+
55
+ ```bash
56
+ mclog latest.log # summary
57
+ mclog latest.log --crashes # errors only
58
+ mclog latest.log --players # player stats table
59
+ mclog latest.log --player Ahmed99 # one player's sessions
60
+ mclog latest.log --export report.json # export to JSON
61
+ ```
62
+
63
+ ---
64
+
65
+ ## Supported Servers
66
+
67
+ | Server | Status |
68
+ |--------|--------|
69
+ | Paper | ✅ |
70
+ | Spigot | ✅ |
71
+ | Vanilla | ✅ |
72
+ | Fabric | ✅ |
73
+ | Forge | 🔜 |
74
+
75
+ ---
76
+
77
+ ## Install
78
+
79
+ ```bash
80
+ pip install mclog-parser
81
+ ```
82
+
83
+ Requires Python 3.10+
84
+
85
+ ---
86
+
87
+ ## Roadmap
88
+
89
+ - [x] Core parser (crashes, lag, sessions)
90
+ - [x] Player stats
91
+ - [x] JSON export
92
+ - [x] CLI
93
+ - [ ] Web dashboard
94
+ - [ ] Discord bot integration
95
+ - [ ] Real-time log watching
96
+
97
+ ---
98
+
99
+ ## License
100
+
101
+ MIT — free to use, modify, and distribute.
@@ -0,0 +1,4 @@
1
+ from .parser import LogParser
2
+
3
+ __version__ = "0.1.0"
4
+ __all__ = ["LogParser"]
@@ -0,0 +1,92 @@
1
+ #!/usr/bin/env python3
2
+ import argparse
3
+ import json
4
+ import sys
5
+ from mclog_parser import LogParser
6
+
7
+
8
+ def main():
9
+ parser = argparse.ArgumentParser(
10
+ prog="mclog",
11
+ description="🎮 Minecraft Log Parser — Analyze your server logs instantly"
12
+ )
13
+ parser.add_argument("logfile", help="Path to latest.log or any MC log file")
14
+ parser.add_argument("--crashes", action="store_true", help="Show crashes and errors")
15
+ parser.add_argument("--lags", action="store_true", help="Show lag spikes")
16
+ parser.add_argument("--players", action="store_true", help="Show player stats")
17
+ parser.add_argument("--player", metavar="NAME", help="Sessions for a specific player")
18
+ parser.add_argument("--export", metavar="FILE", help="Export full report to JSON")
19
+ parser.add_argument("--summary", action="store_true", help="Show summary (default)", default=True)
20
+
21
+ args = parser.parse_args()
22
+
23
+ try:
24
+ log = LogParser(args.logfile)
25
+ except FileNotFoundError as e:
26
+ print(f"❌ {e}", file=sys.stderr)
27
+ sys.exit(1)
28
+
29
+ if args.crashes:
30
+ crashes = log.crashes()
31
+ print(f"\n💥 Crashes & Errors ({len(crashes)} total)\n" + "─" * 40)
32
+ for c in crashes:
33
+ print(f"[{c['time']}] {c['level']}: {c['message']}")
34
+ for t in c["trace"][:3]:
35
+ print(f" {t}")
36
+ return
37
+
38
+ if args.lags:
39
+ lags = log.lag_spikes()
40
+ print(f"\n⚠️ Lag Spikes ({len(lags)} total)\n" + "─" * 40)
41
+ for l in lags:
42
+ print(f"[{l['time']}] {l['message']}")
43
+ return
44
+
45
+ if args.players:
46
+ stats = log.player_stats()
47
+ print(f"\n👥 Player Stats ({len(stats)} players)\n" + "─" * 40)
48
+ print(f"{'Player':<20} {'Sessions':>8} {'Deaths':>7} {'Chat':>6}")
49
+ print("─" * 44)
50
+ for p in stats:
51
+ print(f"{p['player']:<20} {p['sessions']:>8} {p['deaths']:>7} {p['chat_messages']:>6}")
52
+ return
53
+
54
+ if args.player:
55
+ sessions = log.player_sessions(args.player)
56
+ data = sessions.get(args.player, [])
57
+ print(f"\n🎮 Sessions for {args.player} ({len(data)} total)\n" + "─" * 40)
58
+ for s in data:
59
+ left = s["left"] or "still online"
60
+ print(f" Joined: {s['joined']} → Left: {left}")
61
+ return
62
+
63
+ if args.export:
64
+ path = log.export_json(args.export)
65
+ print(f"✅ Report exported to: {path}")
66
+ return
67
+
68
+ # Default: summary
69
+ s = log.summary()
70
+ print(f"""
71
+ 🎮 Minecraft Log Summary
72
+ {"─" * 40}
73
+ 📁 File : {s['file']}
74
+ 📄 Total Lines : {s['total_lines']:,}
75
+ 👥 Players : {s['unique_players']}
76
+ 🔗 Sessions : {s['total_sessions']}
77
+ 💥 Crashes : {s['crash_count']}
78
+ ⚠️ Lag Spikes : {s['lag_spike_count']}
79
+
80
+ 🏆 Top Players:
81
+ """)
82
+ for p in s["top_players"]:
83
+ print(f" {p['player']:<20} {p['sessions']} sessions | {p['deaths']} deaths")
84
+
85
+ if s["crashes"]:
86
+ print(f"\n💥 Latest Crash:")
87
+ c = s["crashes"][-1]
88
+ print(f" [{c['time']}] {c['message']}")
89
+
90
+
91
+ if __name__ == "__main__":
92
+ main()
@@ -0,0 +1,175 @@
1
+ import re
2
+ import json
3
+ from datetime import datetime, timedelta
4
+ from pathlib import Path
5
+ from collections import defaultdict
6
+ from typing import Optional
7
+
8
+
9
+ # ─── Regex Patterns ───────────────────────────────────────────────
10
+ _LINE_RE = re.compile(
11
+ r"^\[(?P<time>\d{2}:\d{2}:\d{2})\] \[(?P<thread>[^\]]+)/(?P<level>[A-Z]+)\]: (?P<msg>.+)$"
12
+ )
13
+ _JOIN_RE = re.compile(r"^(?P<player>\w+) joined the game$")
14
+ _LEAVE_RE = re.compile(r"^(?P<player>\w+) left the game$")
15
+ _DEATH_RE = re.compile(r"^(?P<player>\w+) (?:was|died|fell|drowned|burned|blew|hit|tried|walked|withered|starved|suffocated|kinetic).+$")
16
+ _CHAT_RE = re.compile(r"^<(?P<player>\w+)> (?P<message>.+)$")
17
+ _LAG_RE = re.compile(r"Can't keep up!")
18
+ _CRASH_RE = re.compile(r"(?:java\.\w+Exception|java\.lang\.Error|Caused by:|FATAL)")
19
+
20
+
21
+ class LogParser:
22
+ """
23
+ Parse Minecraft server log files and extract structured data.
24
+
25
+ Usage:
26
+ log = LogParser("latest.log")
27
+ print(log.summary())
28
+ log.export_json("report.json")
29
+ """
30
+
31
+ def __init__(self, filepath: str):
32
+ self.filepath = Path(filepath)
33
+ if not self.filepath.exists():
34
+ raise FileNotFoundError(f"Log file not found: {filepath}")
35
+
36
+ self._lines: list[dict] = []
37
+ self._parse()
38
+
39
+ # ─── Internal ──────────────────────────────────────────────────
40
+
41
+ def _parse(self):
42
+ with open(self.filepath, "r", encoding="utf-8", errors="replace") as f:
43
+ for raw in f:
44
+ raw = raw.rstrip("\n")
45
+ m = _LINE_RE.match(raw)
46
+ if m:
47
+ self._lines.append({
48
+ "time": m.group("time"),
49
+ "thread": m.group("thread"),
50
+ "level": m.group("level"),
51
+ "msg": m.group("msg"),
52
+ "raw": raw,
53
+ })
54
+ else:
55
+ # continuation lines (stack traces etc.)
56
+ if self._lines:
57
+ self._lines[-1].setdefault("extra", []).append(raw)
58
+
59
+ # ─── Public API ────────────────────────────────────────────────
60
+
61
+ def crashes(self) -> list[dict]:
62
+ """Return all crash/error events with context."""
63
+ results = []
64
+ for i, line in enumerate(self._lines):
65
+ if _CRASH_RE.search(line["msg"]) or line["level"] in ("ERROR", "FATAL"):
66
+ results.append({
67
+ "time": line["time"],
68
+ "level": line["level"],
69
+ "message": line["msg"],
70
+ "trace": line.get("extra", []),
71
+ })
72
+ return results
73
+
74
+ def lag_spikes(self) -> list[dict]:
75
+ """Return all lag spike warnings."""
76
+ return [
77
+ {"time": l["time"], "message": l["msg"]}
78
+ for l in self._lines if _LAG_RE.search(l["msg"])
79
+ ]
80
+
81
+ def player_sessions(self, player: Optional[str] = None) -> dict:
82
+ """
83
+ Return join/leave sessions per player.
84
+ If player is given, filter to that player only.
85
+ """
86
+ sessions: dict[str, list] = defaultdict(list)
87
+ last_join: dict[str, str] = {}
88
+
89
+ for line in self._lines:
90
+ jm = _JOIN_RE.match(line["msg"])
91
+ lm = _LEAVE_RE.match(line["msg"])
92
+
93
+ if jm:
94
+ p = jm.group("player")
95
+ last_join[p] = line["time"]
96
+
97
+ elif lm:
98
+ p = lm.group("player")
99
+ sessions[p].append({
100
+ "joined": last_join.pop(p, None),
101
+ "left": line["time"],
102
+ })
103
+
104
+ # players still online (no leave event)
105
+ for p, t in last_join.items():
106
+ sessions[p].append({"joined": t, "left": None})
107
+
108
+ if player:
109
+ return {player: sessions.get(player, [])}
110
+ return dict(sessions)
111
+
112
+ def player_stats(self) -> list[dict]:
113
+ """Return per-player statistics sorted by session count."""
114
+ sessions = self.player_sessions()
115
+ deaths = defaultdict(int)
116
+ messages = defaultdict(int)
117
+
118
+ for line in self._lines:
119
+ dm = _DEATH_RE.match(line["msg"])
120
+ cm = _CHAT_RE.match(line["msg"])
121
+ if dm:
122
+ deaths[dm.group("player")] += 1
123
+ if cm:
124
+ messages[cm.group("player")] += 1
125
+
126
+ stats = []
127
+ all_players = set(sessions) | set(deaths) | set(messages)
128
+ for p in all_players:
129
+ s = sessions.get(p, [])
130
+ stats.append({
131
+ "player": p,
132
+ "sessions": len(s),
133
+ "deaths": deaths[p],
134
+ "chat_messages": messages[p],
135
+ })
136
+
137
+ return sorted(stats, key=lambda x: x["sessions"], reverse=True)
138
+
139
+ def top_players(self, n: int = 10) -> list[dict]:
140
+ """Return top N players by sessions."""
141
+ return self.player_stats()[:n]
142
+
143
+ def summary(self) -> dict:
144
+ """Return a full summary of the log file."""
145
+ stats = self.player_stats()
146
+ crashes = self.crashes()
147
+ lags = self.lag_spikes()
148
+
149
+ unique_players = len(stats)
150
+ total_sessions = sum(p["sessions"] for p in stats)
151
+
152
+ return {
153
+ "file": str(self.filepath),
154
+ "total_lines": len(self._lines),
155
+ "unique_players": unique_players,
156
+ "total_sessions": total_sessions,
157
+ "crash_count": len(crashes),
158
+ "lag_spike_count": len(lags),
159
+ "top_players": self.top_players(5),
160
+ "crashes": crashes[:5], # first 5 only in summary
161
+ }
162
+
163
+ def export_json(self, output_path: str = "mc_report.json") -> str:
164
+ """Export full analysis to a JSON file."""
165
+ report = {
166
+ "summary": self.summary(),
167
+ "player_stats": self.player_stats(),
168
+ "all_crashes": self.crashes(),
169
+ "all_lag_spikes": self.lag_spikes(),
170
+ "player_sessions": self.player_sessions(),
171
+ }
172
+ path = Path(output_path)
173
+ with open(path, "w", encoding="utf-8") as f:
174
+ json.dump(report, f, ensure_ascii=False, indent=2)
175
+ return str(path)
@@ -0,0 +1,115 @@
1
+ Metadata-Version: 2.4
2
+ Name: mclog-parser
3
+ Version: 0.1.0
4
+ Summary: Parse and analyze Minecraft server log files
5
+ License: MIT
6
+ Keywords: minecraft,log,parser,server,analysis
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Topic :: Games/Entertainment
10
+ Requires-Python: >=3.10
11
+ Description-Content-Type: text/markdown
12
+ License-File: LICENSE
13
+ Dynamic: license-file
14
+
15
+ # mclog-parser
16
+ Analyze Minecraft server logs instantly — turn raw log files into structured data.
17
+ # mclog-parser 🎮
18
+
19
+ **Analyze Minecraft server logs instantly — turn raw log files into structured data.**
20
+
21
+ ```bash
22
+ pip install mclog-parser
23
+ ```
24
+
25
+ ---
26
+
27
+ ## Why?
28
+
29
+ Every Minecraft server generates thousands of log lines. Finding crashes, tracking players, or spotting lag spikes means scrolling through walls of text manually.
30
+
31
+ `mclog-parser` does it in one line.
32
+
33
+ ---
34
+
35
+ ## Quickstart
36
+
37
+ ```python
38
+ from mclog_parser import LogParser
39
+
40
+ log = LogParser("latest.log")
41
+
42
+ log.summary() # full overview
43
+ log.crashes() # all errors & crashes
44
+ log.lag_spikes() # lag warnings
45
+ log.player_stats() # per-player stats
46
+ log.export_json() # save report as JSON
47
+ ```
48
+
49
+ ### Example Output
50
+
51
+ ```json
52
+ {
53
+ "unique_players": 3,
54
+ "total_sessions": 5,
55
+ "crash_count": 1,
56
+ "lag_spike_count": 2,
57
+ "top_players": [
58
+ { "player": "Ahmed99", "sessions": 2, "deaths": 1 }
59
+ ]
60
+ }
61
+ ```
62
+
63
+ ---
64
+
65
+ ## CLI
66
+
67
+ No Python needed — run directly from your terminal:
68
+
69
+ ```bash
70
+ mclog latest.log # summary
71
+ mclog latest.log --crashes # errors only
72
+ mclog latest.log --players # player stats table
73
+ mclog latest.log --player Ahmed99 # one player's sessions
74
+ mclog latest.log --export report.json # export to JSON
75
+ ```
76
+
77
+ ---
78
+
79
+ ## Supported Servers
80
+
81
+ | Server | Status |
82
+ |--------|--------|
83
+ | Paper | ✅ |
84
+ | Spigot | ✅ |
85
+ | Vanilla | ✅ |
86
+ | Fabric | ✅ |
87
+ | Forge | 🔜 |
88
+
89
+ ---
90
+
91
+ ## Install
92
+
93
+ ```bash
94
+ pip install mclog-parser
95
+ ```
96
+
97
+ Requires Python 3.10+
98
+
99
+ ---
100
+
101
+ ## Roadmap
102
+
103
+ - [x] Core parser (crashes, lag, sessions)
104
+ - [x] Player stats
105
+ - [x] JSON export
106
+ - [x] CLI
107
+ - [ ] Web dashboard
108
+ - [ ] Discord bot integration
109
+ - [ ] Real-time log watching
110
+
111
+ ---
112
+
113
+ ## License
114
+
115
+ MIT — free to use, modify, and distribute.
@@ -0,0 +1,11 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ mclog_parser/__init__.py
5
+ mclog_parser/cli.py
6
+ mclog_parser/parser.py
7
+ mclog_parser.egg-info/PKG-INFO
8
+ mclog_parser.egg-info/SOURCES.txt
9
+ mclog_parser.egg-info/dependency_links.txt
10
+ mclog_parser.egg-info/entry_points.txt
11
+ mclog_parser.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ mclog = mclog_parser.cli:main
@@ -0,0 +1,3 @@
1
+ dist
2
+ mclog_parser
3
+ tests
@@ -0,0 +1,23 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "mclog-parser"
7
+ version = "0.1.0"
8
+ description = "Parse and analyze Minecraft server log files"
9
+ readme = "README.md"
10
+ license = { text = "MIT" }
11
+ requires-python = ">=3.10"
12
+ keywords = ["minecraft", "log", "parser", "server", "analysis"]
13
+ classifiers = [
14
+ "Programming Language :: Python :: 3",
15
+ "License :: OSI Approved :: MIT License",
16
+ "Topic :: Games/Entertainment",
17
+ ]
18
+
19
+ [project.scripts]
20
+ mclog = "mclog_parser.cli:main"
21
+
22
+ [tool.setuptools.packages.find]
23
+ where = ["."]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+