Parses game log files into structured data
| 554 | |
| 555 | |
| 556 | class LogParser: |
| 557 | """Parses game log files into structured data""" |
| 558 | |
| 559 | def __init__(self, log_dir: Path): |
| 560 | self.log_dir = Path(log_dir) |
| 561 | self._cached_metadata: Metadata | None = None |
| 562 | |
| 563 | def _get_metadata(self) -> Metadata: |
| 564 | """Get cached metadata or load it if not cached""" |
| 565 | if self._cached_metadata is None: |
| 566 | self._cached_metadata = load_metadata(self.log_dir) |
| 567 | return self._cached_metadata |
| 568 | |
| 569 | def parse_game_metadata(self) -> GameMetadata: |
| 570 | """Parse overall game metadata""" |
| 571 | # Load metadata.json |
| 572 | metadata = self._get_metadata() |
| 573 | if not metadata.is_valid: |
| 574 | results = {"status": "No metadata file found"} |
| 575 | metadata_file_path = "" |
| 576 | else: |
| 577 | results = metadata.raw_data |
| 578 | metadata_file_path = str(self.log_dir / "metadata.json") |
| 579 | |
| 580 | # Get path to main log but don't load content |
| 581 | main_log_file = self.log_dir / "tournament.log" |
| 582 | main_log_path = str(main_log_file) if main_log_file.exists() else "" |
| 583 | |
| 584 | # Parse all available logs (metadata only, no content) |
| 585 | all_logs = self._parse_all_logs() |
| 586 | |
| 587 | # Extract agent information once |
| 588 | agent_info = get_agent_info_from_metadata(metadata) |
| 589 | |
| 590 | # Parse round data from metadata.json round_stats |
| 591 | rounds = [] |
| 592 | round_stats = metadata.round_stats |
| 593 | if round_stats: |
| 594 | # Process each round from round_stats |
| 595 | for round_key, round_data in round_stats.items(): |
| 596 | round_num = int(round_key) |
| 597 | round_results = process_round_results(round_data, agent_info) |
| 598 | rounds.append({"round_num": round_num, "sim_logs": [], "results": round_results}) |
| 599 | |
| 600 | # Sort rounds by round number to ensure consistent ordering |
| 601 | rounds.sort(key=lambda x: x["round_num"]) |
| 602 | |
| 603 | return GameMetadata( |
| 604 | results=results, |
| 605 | main_log_path=main_log_path, |
| 606 | metadata_file_path=metadata_file_path, |
| 607 | rounds=rounds, |
| 608 | agent_info=agent_info, |
| 609 | all_logs=all_logs, |
| 610 | ) |
| 611 | |
| 612 | def parse_trajectory( |
| 613 | self, player_name: str, round_num: int, *, load_diffs: bool = False, load_messages: bool = False |
no outgoing calls
no test coverage detected