Passed
Pull Request — 1.x (#334)
by Akihito
02:30
created

DevLogPersister   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 68
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 39
c 1
b 0
f 1
dl 0
loc 68
rs 10
wmc 9

5 Methods

Rating   Name   Duplication   Size   Complexity  
A saveToFile() 0 14 2
A generateFilename() 0 12 2
A getAnalysisPrompt() 0 3 1
A __construct() 0 10 2
A persistLogs() 0 6 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace BEAR\Resource\SemanticLog;
6
7
use Koriym\SemanticLogger\LogJson;
8
use Koriym\SemanticLogger\SemanticLoggerInterface;
9
use Ray\Di\Di\Named;
10
use Throwable;
11
12
use function date;
13
use function file_put_contents;
14
use function getmypid;
15
use function json_encode;
16
use function sprintf;
17
use function str_replace;
18
use function sys_get_temp_dir;
19
use function uniqid;
20
21
use const JSON_PRETTY_PRINT;
22
use const JSON_UNESCAPED_SLASHES;
23
use const LOCK_EX;
24
25
/**
26
 * Development log persister for MCP server integration
27
 *
28
 * Handles file persistence of semantic logs with Profile data for AI-assisted debugging.
29
 * Uses single responsibility principle - only concerned with log persistence.
30
 */
31
final class DevLogPersister
32
{
33
    public function __construct(
34
        #[Named('dev_log_directory')]
35
        private string $logDirectory = '',
36
    ) {
37
        // Use system temp directory if no directory specified
38
        if ($this->logDirectory !== '') {
39
            return;
40
        }
41
42
        $this->logDirectory = sys_get_temp_dir();
43
    }
44
45
    /**
46
     * Persist semantic logs to file for development/debugging purposes
47
     */
48
    public function persistLogs(SemanticLoggerInterface $logger): void
49
    {
50
        try {
51
            $logData = $logger->flush();
52
            $this->saveToFile($logData);
53
        } catch (Throwable) {
54
            // Silent failure - don't break main processing
55
            // In development, log persistence should never affect application flow
56
        }
57
    }
58
59
    private function saveToFile(LogJson $logData): void
60
    {
61
        $jsonContent = json_encode($logData, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
62
        if ($jsonContent === false) {
63
            return; // Skip if JSON encoding fails
64
        }
65
66
        $filename = $this->generateFilename();
67
        file_put_contents($filename, $jsonContent, LOCK_EX);
68
69
        // Save analysis prompt alongside JSON for AI-native processing
70
        $promptFilename = str_replace('.json', '-prompt.md', $filename);
71
        $analysisPrompt = $this->getAnalysisPrompt() . "\n\n```json\n" . $jsonContent . "\n```";
72
        file_put_contents($promptFilename, $analysisPrompt, LOCK_EX);
73
    }
74
75
    /**
76
     * Generate unique filename for concurrent request safety
77
     */
78
    private function generateFilename(): string
79
    {
80
        $timestamp = date('Y-m-d_H-i-s-u'); // Microseconds for concurrency
81
        $processId = getmypid(); // Process ID for true uniqueness
82
        $uniqueId = uniqid();
83
84
        return sprintf(
85
            '%s/semantic-dev-%s-%s-%s.json',
86
            $this->logDirectory,
87
            $timestamp,
88
            $processId !== false ? $processId : 'unknown',
89
            $uniqueId,
90
        );
91
    }
92
93
    /**
94
     * Generate analysis prompt for AI-native semantic web processing
95
     */
96
    private function getAnalysisPrompt(): string
97
    {
98
        return <<<'PROMPT'
99
This is a BEAR.Resource application profiling log. Analyze YOUR APPLICATION CODE performance, not the framework itself.
100
101
The log contains schemaUrl fields. If necessary, refer to these schemas to understand the semantic meaning of the data structures.
102
103
Focus on business logic within resource methods and application-specific code. Ignore framework overhead and profiling overhead.
104
105
If no performance issues are found, provide:
106
- What the code is doing (business purpose)
107
- How it's implemented (technical approach)
108
- Implementation assessment (is this approach appropriate for the task?)
109
- Any architectural observations or suggestions for production readiness
110
111
Use the semantic profiling data to provide deep insights about code quality and appropriateness, not just performance metrics.
112
PROMPT;
113
    }
114
}
115