1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace LaravelPlus\Extension\Commands; |
4
|
|
|
|
5
|
|
|
use Illuminate\Console\Command; |
6
|
|
|
use Symfony\Component\Process\Process; |
7
|
|
|
use Carbon\Carbon; |
8
|
|
|
|
9
|
|
|
class TailCommand extends Command |
10
|
|
|
{ |
11
|
|
|
/** |
12
|
|
|
* The console command signature. |
13
|
|
|
* |
14
|
|
|
* @var string |
15
|
|
|
*/ |
16
|
|
|
protected $signature = 'tail |
17
|
|
|
{connection? : The name of remote.} |
18
|
|
|
{--path= : The fully qualified path to the log file.} |
19
|
|
|
{--lines=20 : The number of lines to tail.} |
20
|
|
|
'; |
21
|
|
|
|
22
|
|
|
/** |
23
|
|
|
* The console command description. |
24
|
|
|
* |
25
|
|
|
* @var string |
26
|
|
|
*/ |
27
|
|
|
protected $description = '[+] Tail a log file'; |
28
|
|
|
|
29
|
|
|
/** |
30
|
|
|
* Execute the console command. |
31
|
|
|
*/ |
32
|
5 |
|
public function handle() |
33
|
|
|
{ |
34
|
|
|
// syslog not support |
35
|
5 |
|
if ($this->laravel['config']['app.log'] === 'syslog') { |
36
|
1 |
|
$this->error('syslog not support.'); |
37
|
|
|
|
38
|
1 |
|
return; |
39
|
|
|
} |
40
|
|
|
|
41
|
4 |
|
$connection = $this->argument('connection'); |
42
|
|
|
|
43
|
|
|
// on Local |
44
|
4 |
|
if (is_null($connection)) { |
45
|
2 |
|
$path = $this->option('path') ?: $this->getLocalPath(); |
46
|
|
|
|
47
|
2 |
|
if ($path) { |
48
|
1 |
|
$this->tailLocalLogs($path); |
49
|
|
|
} else { |
50
|
2 |
|
$this->error('Could not determine path to log file.'); |
51
|
|
|
} |
52
|
|
|
} |
53
|
|
|
// on Remote |
54
|
|
|
else { |
55
|
2 |
|
$path = $this->option('path') ?: $this->getRemotePath($connection); |
56
|
|
|
|
57
|
2 |
|
if ($path) { |
58
|
1 |
|
$this->tailRemoteLogs($path, $connection); |
59
|
|
|
} else { |
60
|
1 |
|
$this->error('Could not determine path to log file.'); |
61
|
|
|
} |
62
|
|
|
} |
63
|
4 |
|
} |
64
|
|
|
|
65
|
|
|
/** |
66
|
|
|
* Get the path to the Laravel log file. |
67
|
|
|
* |
68
|
|
|
* @return string |
69
|
|
|
*/ |
70
|
1 |
View Code Duplication |
protected function getLocalPath() |
|
|
|
|
71
|
|
|
{ |
72
|
1 |
|
switch ($this->laravel['config']['app.log']) { |
73
|
1 |
|
case 'single': |
74
|
|
|
return storage_path('logs/laravel.log'); |
75
|
|
|
|
76
|
1 |
|
case 'daily': |
77
|
|
|
$date = Carbon::today()->format('Y-m-d'); |
78
|
|
|
|
79
|
|
|
return storage_path("logs/laravel-{$date}.log"); |
80
|
|
|
|
81
|
1 |
|
case 'syslog': |
82
|
|
|
throw new \RuntimeException('syslog not support'); |
83
|
|
|
} |
84
|
1 |
|
} |
85
|
|
|
|
86
|
|
|
/** |
87
|
|
|
* Tail a local log file for the application. |
88
|
|
|
* |
89
|
|
|
* @param string $path |
90
|
|
|
* |
91
|
|
|
* @return string |
92
|
|
|
*/ |
93
|
1 |
View Code Duplication |
protected function tailLocalLogs($path) |
|
|
|
|
94
|
|
|
{ |
95
|
1 |
|
$output = $this->output; |
96
|
|
|
|
97
|
1 |
|
$lines = $this->option('lines'); |
98
|
|
|
|
99
|
1 |
|
(new Process('tail -f -n '.$lines.' '.escapeshellarg($path)))->setTimeout(null)->run(function ($type, $line) use ($output) { |
100
|
1 |
|
$output->write($line); |
101
|
1 |
|
}); |
102
|
1 |
|
} |
103
|
|
|
|
104
|
|
|
/** |
105
|
|
|
* Get the path to the Laravel log file. |
106
|
|
|
* |
107
|
|
|
* @param string $connection |
108
|
|
|
* |
109
|
|
|
* @return string |
110
|
|
|
*/ |
111
|
1 |
|
protected function getRemotePath($connection) |
112
|
|
|
{ |
113
|
1 |
|
return $this->getRoot($connection).str_replace(base_path(), '', $this->getRemotePathFromStorage()); |
114
|
|
|
} |
115
|
|
|
|
116
|
|
|
/** |
117
|
|
|
* Get the path to the Laravel log file. |
118
|
|
|
* |
119
|
|
|
* @return string |
120
|
|
|
*/ |
121
|
1 |
View Code Duplication |
protected function getRemotePathFromStorage() |
|
|
|
|
122
|
|
|
{ |
123
|
1 |
|
switch ($this->laravel['config']['app.log']) { |
124
|
1 |
|
case 'single': |
125
|
|
|
return storage_path('logs/laravel.log'); |
126
|
|
|
|
127
|
1 |
|
case 'daily': |
128
|
|
|
$date = Carbon::today()->format('Y-m-d'); |
129
|
|
|
|
130
|
|
|
return storage_path("logs/laravel-{$date}.log"); |
131
|
|
|
|
132
|
1 |
|
case 'syslog': |
133
|
|
|
throw new \RuntimeException('syslog not support'); |
134
|
|
|
} |
135
|
1 |
|
} |
136
|
|
|
|
137
|
|
|
/** |
138
|
|
|
* Get the path to the Laravel install root. |
139
|
|
|
* |
140
|
|
|
* @param string $connection |
141
|
|
|
* |
142
|
|
|
* @return string |
143
|
|
|
*/ |
144
|
1 |
|
protected function getRoot($connection) |
145
|
|
|
{ |
146
|
1 |
|
return $this->laravel['config']['remote.connections.'.$connection.'.root']; |
147
|
|
|
} |
148
|
|
|
|
149
|
|
|
/** |
150
|
|
|
* Tail a remote log file at the given path and connection. |
151
|
|
|
* |
152
|
|
|
* @param string $path |
153
|
|
|
* @param string $connection |
154
|
|
|
*/ |
155
|
1 |
View Code Duplication |
protected function tailRemoteLogs($path, $connection) |
|
|
|
|
156
|
|
|
{ |
157
|
1 |
|
$out = $this->output; |
158
|
|
|
|
159
|
1 |
|
$lines = $this->option('lines'); |
160
|
|
|
|
161
|
1 |
|
$this->getRemote($connection)->run('tail -f -n '.$lines.' '.escapeshellarg($path), function ($line) use ($out) { |
162
|
|
|
$out->write($line); |
163
|
1 |
|
}); |
164
|
1 |
|
} |
165
|
|
|
|
166
|
|
|
/** |
167
|
|
|
* Get a connection to the remote server. |
168
|
|
|
* |
169
|
|
|
* @param string $connection |
170
|
|
|
* |
171
|
|
|
* @return \Illuminate\Remote\Connection |
172
|
|
|
*/ |
173
|
1 |
|
protected function getRemote($connection) |
174
|
|
|
{ |
175
|
1 |
|
return $this->laravel['remote']->connection($connection); |
176
|
|
|
} |
177
|
|
|
} |
178
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.