Passed
Pull Request — master (#2)
by Wilmer
02:40
created

FileTarget::setFilename()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
cc 1
nc 1
nop 1
crap 1
1
<?php
2
declare(strict_types=1);
3
4
namespace Yiisoft\Profiler;
5
6
use Yiisoft\Files\FileHelper;
7
8
/**
9
 * FileTarget records profiling messages in a file specified via {@see filename}.
10
 *
11
 * Application configuration example:
12
 *
13
 * ```php
14
 * return [
15
 *     'profiler' => [
16
 *         'targets' => [
17
 *             [
18
 *                 '__class' => Yiisoft\Profile\FileTarget::class,
19
 *                 //'filename' => '@runtime/profiling/{date}-{time}.txt',
20
 *             ],
21
 *         ],
22
 *         // ...
23
 *     ],
24
 *     // ...
25
 * ];
26
 * ```
27
 */
28
class FileTarget extends Target
29
{
30
    /**
31
     * @var string file path or [path alias](guide:concept-aliases). File name may contain the placeholders,
32
     * which will be replaced by computed values. The supported placeholders are:
33
     *
34
     * - '{ts}' - profiling completion timestamp.
35
     * - '{date}' - profiling completion date in format 'ymd'.
36
     * - '{time}' - profiling completion time in format 'His'.
37
     *
38
     * The directory containing the file will be automatically created if not existing.
39
     * If target file is already exist it will be overridden.
40
     */
41
    private string $filename = '@runtime/profiling/{date}-{time}.txt';
42
43
    /**
44
     * @var int the permission to be set for newly created files.
45
     * This value will be used by PHP chmod() function. No umask will be applied.
46
     * If not set, the permission will be determined by the current environment.
47
     */
48
    private int $fileMode = 0755;
0 ignored issues
show
introduced by
The private property $fileMode is not used, and could be removed.
Loading history...
49
50
    /**
51
     * @var int the permission to be set for newly created directories.
52
     * This value will be used by PHP chmod() function. No umask will be applied.
53
     * Defaults to 0775, meaning the directory is read-writable by owner and group,
54
     * but read-only for other users.
55
     */
56
    private int $dirMode = 0775;
57
58
    /**
59
     * {@inheritdoc}
60
     */
61 1
    public function export(array $messages): void
62
    {
63 1
        $memoryPeakUsage = memory_get_peak_usage();
64
65
        // TODO: make sure it works with RoadRunner and alike servers
66 1
        $totalTime = microtime(true) - $_SERVER['REQUEST_TIME_FLOAT'];
67 1
        $text = "Total processing time: {$totalTime} ms; Peak memory: {$memoryPeakUsage} B. \n\n";
68
69 1
        $text .= implode("\n", array_map([$this, 'formatMessage'], $messages));
70
71 1
        $filename = $this->resolveFilename();
72
73 1
        if (file_exists($filename)) {
74
            unlink($filename);
75
        } else {
76 1
            $filePath = dirname($filename);
77
78 1
            if (!is_dir($filePath)) {
79 1
                FileHelper::createDirectory($filePath, $this->dirMode);
80
            }
81
        }
82
83 1
        file_put_contents($filename, $text);
84
    }
85
86
    /**
87
     * Set profiles filename
88
     *
89
     * @param string $value
90
     *
91
     * @return void
92
     *
93
     * {@see filename}
94
     */
95 1
    public function setFilename(string $value): void
96
    {
97 1
        $this->filename = $value;
98
    }
99
100
    /**
101
     * Resolves value of {@see filename} processing path alias and placeholders.
102
     *
103
     * @return string actual target filename.
104
     */
105 1
    protected function resolveFilename(): string
106
    {
107 1
        $filename = $this->filename;
108
109
        return preg_replace_callback('/{\\w+}/', function ($matches) {
110
            switch ($matches[0]) {
111
                case '{ts}':
112
                    return time();
113
                case '{date}':
114
                    return gmdate('ymd');
115
                case '{time}':
116
                    return gmdate('His');
117
            }
118
            return $matches[0];
119 1
        }, $filename);
120
    }
121
122
    /**
123
     * Formats a profiling message for display as a string.
124
     *
125
     * @param array $message the profiling message to be formatted.
126
     * The message structure follows that in {@see Profiler::$messages}.
127
     *
128
     * @return string the formatted message.
129
     */
130 1
    protected function formatMessage(array $message): string
131
    {
132 1
        return date(
133 1
            'Y-m-d H:i:s',
134 1
            (int) $message['beginTime']
135 1
        ) . " [{$message['duration']} ms][{$message['memoryDiff']} B][{$message['category']}] {$message['token']}" .
136 1
        __METHOD__;
137
    }
138
}
139