{"id":35128557,"url":"https://github.com/zichkoding/log_analyzer","last_synced_at":"2026-05-18T20:03:36.079Z","repository":{"id":321498814,"uuid":"1085372508","full_name":"ZichKoding/log_analyzer","owner":"ZichKoding","description":null,"archived":false,"fork":false,"pushed_at":"2025-10-30T01:06:57.000Z","size":23,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-10-30T01:25:02.937Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ZichKoding.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-29T00:29:24.000Z","updated_at":"2025-10-30T01:07:00.000Z","dependencies_parsed_at":"2025-10-30T01:26:35.590Z","dependency_job_id":"5fa7ec90-9ecc-4f2b-a48e-e69503204df7","html_url":"https://github.com/ZichKoding/log_analyzer","commit_stats":null,"previous_names":["zichkoding/log_analyzer"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/ZichKoding/log_analyzer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ZichKoding%2Flog_analyzer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ZichKoding%2Flog_analyzer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ZichKoding%2Flog_analyzer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ZichKoding%2Flog_analyzer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ZichKoding","download_url":"https://codeload.github.com/ZichKoding/log_analyzer/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ZichKoding%2Flog_analyzer/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33189279,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-18T09:27:30.708Z","status":"ssl_error","status_checked_at":"2026-05-18T09:27:28.300Z","response_time":71,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-12-28T04:03:14.707Z","updated_at":"2026-05-18T20:03:36.074Z","avatar_url":"https://github.com/ZichKoding.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Challenge 1: Log Analyzer Web Dashboard (30 minutes, Beginner)\n\n## Problem Statement\n\nBuild a simple HTTP server that reads server log files, analyzes them, and displays statistics through a web interface. This challenge introduces basic web server concepts, simple data structures, and file processing.\n\n## Specific Requirements\n\nCreate a program that:\n\n1. **Reads log files** from a `logs/` directory containing entries like:\n   ```\n   2025-10-20 14:23:15 INFO User login: john@example.com\n   2025-10-20 14:24:03 ERROR Database connection failed\n   2025-10-20 14:25:10 INFO User logout: jane@example.com\n   ```\n\n2. **Analyzes logs** to extract:\n   - Total number of entries\n   - Count by log level (INFO, WARNING, ERROR)\n   - Most recent 5 log entries\n   - Count of unique users mentioned\n\n3. **Serves a simple web interface** with:\n   - Homepage displaying statistics as HTML\n   - `/api/stats` endpoint returning JSON data\n   - Basic error handling for missing files\n\n4. **Uses only standard library**: `http.server`, `pathlib`, `json`, `collections`, `datetime`\n\n## Implementation Requirements\n\n```python\nfrom http.server import HTTPServer, BaseHTTPRequestHandler\nfrom pathlib import Path\nfrom collections import Counter\nimport json\n\nclass LogAnalyzerHandler(BaseHTTPRequestHandler):\n    def do_GET(self):\n        # Implement routing for / and /api/stats\n        pass\n\n    def analyze_logs(self) -\u003e dict:\n        # Read and analyze log files\n        pass\n```\n\n## Success Criteria\n\n- ✅ Server starts on port 8000 without errors\n- ✅ Homepage displays log statistics in readable HTML\n- ✅ `/api/stats` returns valid JSON with all required metrics\n- ✅ Handles missing log directory gracefully (no crashes)\n- ✅ Uses `pathlib` for all file operations\n- ✅ Properly counts log levels using `Counter`\n- ✅ Code includes type hints on main functions\n\n## Example Use Cases\n\n**Test Setup:**\n```python\n# Create logs directory with sample data\nPath('logs').mkdir(exist_ok=True)\nPath('logs/server.log').write_text(\"\"\"\n2025-10-20 14:23:15 INFO User login: john@example.com\n2025-10-20 14:24:03 ERROR Database connection failed\n2025-10-20 14:25:10 INFO User logout: jane@example.com\n2025-10-20 14:26:22 WARNING High memory usage detected\n2025-10-20 14:27:05 INFO User login: alice@example.com\n\"\"\")\n```\n\n**Expected Output at `/api/stats`:**\n```json\n{\n  \"total_entries\": 5,\n  \"by_level\": {\n    \"INFO\": 3,\n    \"ERROR\": 1,\n    \"WARNING\": 1\n  },\n  \"unique_users\": 3,\n  \"recent_entries\": [\n    \"2025-10-20 14:27:05 INFO User login: alice@example.com\",\n    \"2025-10-20 14:26:22 WARNING High memory usage detected\",\n    \"2025-10-20 14:25:10 INFO User logout: jane@example.com\",\n    \"2025-10-20 14:24:03 ERROR Database connection failed\",\n    \"2025-10-20 14:23:15 INFO User login: john@example.com\"\n  ]\n}\n```\n\n## Hints and Guidance\n\n1. **File Reading Pattern**:\n   ```python\n   log_files = Path('logs').glob('*.log')\n   for log_file in log_files:\n       content = log_file.read_text()\n       lines = content.strip().splitlines()\n   ```\n\n2. **Parsing Log Lines**: Use `str.split()` with maxsplit to separate timestamp, level, and message:\n   ```python\n   parts = line.split(maxsplit=3)  # ['2025-10-20', '14:23:15', 'INFO', 'message...']\n   ```\n\n3. **Counting**: Use `collections.Counter` for efficient counting:\n   ```python\n   from collections import Counter\n   levels = Counter()\n   levels[log_level] += 1\n   ```\n\n4. **HTML Response Template**:\n   ```python\n   html = f\"\"\"\n   \u003c!DOCTYPE html\u003e\n   \u003chtml\u003e\n   \u003chead\u003e\u003ctitle\u003eLog Analyzer\u003c/title\u003e\u003c/head\u003e\n   \u003cbody\u003e\n       \u003ch1\u003eServer Log Statistics\u003c/h1\u003e\n       \u003cp\u003eTotal Entries: {stats['total_entries']}\u003c/p\u003e\n       \u003ch2\u003eBy Level:\u003c/h2\u003e\n       \u003cul\u003e\n           \u003cli\u003eINFO: {stats['by_level'].get('INFO', 0)}\u003c/li\u003e\n           \u003cli\u003eWARNING: {stats['by_level'].get('WARNING', 0)}\u003c/li\u003e\n           \u003cli\u003eERROR: {stats['by_level'].get('ERROR', 0)}\u003c/li\u003e\n       \u003c/ul\u003e\n   \u003c/body\u003e\n   \u003c/html\u003e\n   \"\"\"\n   ```\n\n5. **JSON Serialization**: Convert Counter to dict for JSON:\n   ```python\n   json.dumps({'by_level': dict(counter)})\n   ```\n\n## Bonus Challenges\n\n1. **Email Extraction** (⭐): Use regex to extract and count all email addresses mentioned in logs\n2. **Time Range Filtering** (⭐): Add query parameters like `/api/stats?hours=24` to filter recent logs\n3. **Error Rate Alert** (⭐⭐): Display a warning if ERROR count exceeds 10% of total entries\n4. **Multiple Files** (⭐⭐): Handle multiple `.log` files in the directory and combine statistics\n5. **Live Refresh** (⭐⭐⭐): Add auto-refresh to HTML using `\u003cmeta\u003e` tag so page updates every 5 seconds\n\n## Testing Your Solution\n\n```python\n# test_challenge1.py\nimport unittest\nfrom pathlib import Path\nimport requests\nimport subprocess\nimport time\n\nclass TestLogAnalyzer(unittest.TestCase):\n    @classmethod\n    def setUpClass(cls):\n        # Start server in background\n        cls.server_process = subprocess.Popen(['python', 'challenge1.py'])\n        time.sleep(2)  # Wait for server to start\n\n    @classmethod\n    def tearDownClass(cls):\n        cls.server_process.terminate()\n\n    def test_homepage(self):\n        response = requests.get('http://localhost:8000/')\n        self.assertEqual(response.status_code, 200)\n        self.assertIn('Log Statistics', response.text)\n\n    def test_api_stats(self):\n        response = requests.get('http://localhost:8000/api/stats')\n        self.assertEqual(response.status_code, 200)\n        data = response.json()\n        self.assertIn('total_entries', data)\n        self.assertIn('by_level', data)\n```\n\n## Learning Outcomes\n\n- HTTP request/response cycle\n- Basic routing concepts\n- File I/O with pathlib\n- Simple data aggregation\n- JSON serialization\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzichkoding%2Flog_analyzer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzichkoding%2Flog_analyzer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzichkoding%2Flog_analyzer/lists"}