Merge branch 'develop'
This commit is contained in:
5
Dockerfile
Normal file
5
Dockerfile
Normal file
@ -0,0 +1,5 @@
|
||||
FROM php:8-fpm
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY ./php-errors.ini /usr/local/etc/php/conf.d/docker-php-errors.ini
|
16
app/common/Controller/Base.php
Normal file
16
app/common/Controller/Base.php
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
namespace ProVM\Common\Controller;
|
||||
|
||||
use ProVM\Common\Service\Logs;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Slim\Views\Blade as View;
|
||||
|
||||
class Base
|
||||
{
|
||||
public function __invoke(ServerRequestInterface $request, ResponseInterface $response, View $view, Logs $service): ResponseInterface
|
||||
{
|
||||
$files = $service->getFiles();
|
||||
return $view->render($response, 'home', compact('files'));
|
||||
}
|
||||
}
|
25
app/common/Controller/Logs.php
Normal file
25
app/common/Controller/Logs.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
namespace ProVM\Common\Controller;
|
||||
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Slim\Views\Blade as View;
|
||||
use ProVM\Common\Service\Logs as Service;
|
||||
use ProVM\Logview\Log;
|
||||
|
||||
class Logs
|
||||
{
|
||||
public function get(ServerRequestInterface $request, ResponseInterface $response, View $view, Service $service, string $log_file): ResponseInterface
|
||||
{
|
||||
$log = $service->get($log_file);
|
||||
|
||||
$levels = [];
|
||||
foreach (Log::LEVELS as $level) {
|
||||
$levels[strtolower($level)] = (object) [
|
||||
'text' => Log::COLORS[$level],
|
||||
'background' => Log::BACKGROUNDS[$level],
|
||||
];
|
||||
}
|
||||
return $view->render($response, 'logs.show', compact('log', 'levels'));
|
||||
}
|
||||
}
|
44
app/common/Service/Logs.php
Normal file
44
app/common/Service/Logs.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
namespace ProVM\Common\Service;
|
||||
|
||||
use ProVM\Logview\Log\File;
|
||||
|
||||
class Logs
|
||||
{
|
||||
public function __construct(string $folder)
|
||||
{
|
||||
$this
|
||||
->setFolder($folder);
|
||||
}
|
||||
|
||||
protected string $folder;
|
||||
|
||||
public function getFolder(): string
|
||||
{
|
||||
return $this->folder;
|
||||
}
|
||||
|
||||
public function setFolder(string $folder): Logs
|
||||
{
|
||||
$this->folder = $folder;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getFiles(): array
|
||||
{
|
||||
$files = new \FilesystemIterator($this->getFolder());
|
||||
$output = [];
|
||||
foreach ($files as $file) {
|
||||
if ($file->isDir()) {
|
||||
continue;
|
||||
}
|
||||
$output []= $file;
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
public function get(string $log_file): File
|
||||
{
|
||||
$content = \Safe\file_get_contents(implode(DIRECTORY_SEPARATOR, [$this->getFolder(), $log_file]));
|
||||
return (new File())->setFilename($log_file)->setContent($content);
|
||||
}
|
||||
}
|
34
app/composer.json
Normal file
34
app/composer.json
Normal file
@ -0,0 +1,34 @@
|
||||
{
|
||||
"name": "provm/logview",
|
||||
"description": "Monolog log file viewer",
|
||||
"type": "project",
|
||||
"require": {
|
||||
"berrnd/slim-blade-view": "^1.0",
|
||||
"monolog/monolog": "^3.3",
|
||||
"nyholm/psr7": "^1.5",
|
||||
"nyholm/psr7-server": "^1.0",
|
||||
"php-di/php-di": "^7.0",
|
||||
"php-di/slim-bridge": "^3.3",
|
||||
"slim/slim": "^4.11",
|
||||
"thecodingmachine/safe": "^2.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^10.0",
|
||||
"kint-php/kint": "^5.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"ProVM\\Logview\\": "src/",
|
||||
"ProVM\\Common\\": "common/"
|
||||
}
|
||||
},
|
||||
"authors": [
|
||||
{
|
||||
"name": "Aldarien",
|
||||
"email": "aldarien85@gmail.com"
|
||||
}
|
||||
],
|
||||
"config": {
|
||||
"sort-packages": true
|
||||
}
|
||||
}
|
16
app/public/index.php
Normal file
16
app/public/index.php
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
$app = require_once implode(DIRECTORY_SEPARATOR, [
|
||||
dirname(__FILE__, 2),
|
||||
'setup',
|
||||
'app.php'
|
||||
]);
|
||||
Monolog\ErrorHandler::register($app->getContainer()->get(LoggerInterface::class));
|
||||
try {
|
||||
$app->run();
|
||||
} catch (Exception $e) {
|
||||
$app->getContainer()->get(LoggerInterface::class)->alert($e);
|
||||
} catch (Error $e) {
|
||||
$app->getContainer()->get(LoggerInterface::class)->error($e);
|
||||
}
|
9
app/resources/routes/01_logs.php
Normal file
9
app/resources/routes/01_logs.php
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
use ProVM\Common\Controller\Logs;
|
||||
|
||||
$app->group('/logs', function($app) {
|
||||
$app->get('[/]', Logs::class);
|
||||
});
|
||||
$app->group('/log/{log_file}', function($app) {
|
||||
$app->get('[/]', [Logs::class, 'get']);
|
||||
});
|
4
app/resources/routes/99_base.php
Normal file
4
app/resources/routes/99_base.php
Normal file
@ -0,0 +1,4 @@
|
||||
<?php
|
||||
use ProVM\Common\Controller\Base;
|
||||
|
||||
$app->get('[/]', Base::class);
|
11
app/resources/views/home.blade.php
Normal file
11
app/resources/views/home.blade.php
Normal file
@ -0,0 +1,11 @@
|
||||
@extends('layout.base')
|
||||
|
||||
@section('page_content')
|
||||
<div class="ui container">
|
||||
<div class="ui list">
|
||||
@foreach ($files as $file)
|
||||
<a class="item" href="{{$urls->base}}/log/{{urlencode($file->getBasename())}}">{{$file->getBasename()}}</a>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
5
app/resources/views/layout/base.blade.php
Normal file
5
app/resources/views/layout/base.blade.php
Normal file
@ -0,0 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="es">
|
||||
@include('layout.head')
|
||||
@include('layout.body')
|
||||
</html>
|
6
app/resources/views/layout/body.blade.php
Normal file
6
app/resources/views/layout/body.blade.php
Normal file
@ -0,0 +1,6 @@
|
||||
<body>
|
||||
@include('layout.body.header')
|
||||
@yield('page_content')
|
||||
@include('layout.body.footer')
|
||||
@include('layout.body.scripts')
|
||||
</body>
|
0
app/resources/views/layout/body/footer.blade.php
Normal file
0
app/resources/views/layout/body/footer.blade.php
Normal file
5
app/resources/views/layout/body/header.blade.php
Normal file
5
app/resources/views/layout/body/header.blade.php
Normal file
@ -0,0 +1,5 @@
|
||||
<nav class="ui menu">
|
||||
<div class="ui container">
|
||||
<a class="item" href="/">Home</a>
|
||||
</div>
|
||||
</nav>
|
4
app/resources/views/layout/body/scripts.blade.php
Normal file
4
app/resources/views/layout/body/scripts.blade.php
Normal file
@ -0,0 +1,4 @@
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.3/jquery.min.js" integrity="sha512-STof4xm1wgkfm7heWqFJVn58Hm3EtS31XFaagaa8VMReCXAkQnJZ+jEy8PCC/iT18dFy95WcExNHFTqLyp72eQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/fomantic-ui/2.9.2/semantic.min.js" integrity="sha512-5cguXwRllb+6bcc2pogwIeQmQPXEzn2ddsqAexIBhh7FO1z5Hkek1J9mrK2+rmZCTU6b6pERxI7acnp1MpAg4Q==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||
|
||||
@stack('page_scripts')
|
10
app/resources/views/layout/head.blade.php
Normal file
10
app/resources/views/layout/head.blade.php
Normal file
@ -0,0 +1,10 @@
|
||||
<head>
|
||||
<meta charset="utf8" />
|
||||
@hasSection('page_title')
|
||||
<title>Logs - @yield('page_title')</title>
|
||||
@else
|
||||
<title>Logs</title>
|
||||
@endif
|
||||
|
||||
@include('layout.head.styles')
|
||||
</head>
|
3
app/resources/views/layout/head/styles.blade.php
Normal file
3
app/resources/views/layout/head/styles.blade.php
Normal file
@ -0,0 +1,3 @@
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fomantic-ui/2.9.2/semantic.min.css" integrity="sha512-n//BDM4vMPvyca4bJjZPDh7hlqsQ7hqbP9RH18GF2hTXBY5amBwM2501M0GPiwCU/v9Tor2m13GOTFjk00tkQA==" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
||||
|
||||
@stack('page_styles')
|
40
app/setup/app.php
Normal file
40
app/setup/app.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
use DI\ContainerBuilder;
|
||||
use DI\Bridge\Slim\Bridge;
|
||||
|
||||
require_once 'composer.php';
|
||||
|
||||
$builder = new ContainerBuilder();
|
||||
|
||||
$folders = [
|
||||
'settings',
|
||||
'setups'
|
||||
];
|
||||
foreach ($folders as $f) {
|
||||
$folder = implode(DIRECTORY_SEPARATOR, [__DIR__, $f]);
|
||||
if (!file_exists($folder)) {
|
||||
continue;
|
||||
}
|
||||
$files = new FilesystemIterator($folder);
|
||||
foreach ($files as $file) {
|
||||
if ($file->isDir()) {
|
||||
continue;
|
||||
}
|
||||
$builder->addDefinitions($file->getRealPath());
|
||||
}
|
||||
}
|
||||
|
||||
$app = Bridge::create($builder->build());
|
||||
|
||||
$folder = implode(DIRECTORY_SEPARATOR, [__DIR__, 'middlewares']);
|
||||
if (file_exists($folder)) {
|
||||
$files = new FilesystemIterator($folder);
|
||||
foreach ($files as $file) {
|
||||
if ($file->isDir()) {
|
||||
continue;
|
||||
}
|
||||
include_once $file->getRealPath();
|
||||
}
|
||||
}
|
||||
|
||||
return $app;
|
6
app/setup/composer.php
Normal file
6
app/setup/composer.php
Normal file
@ -0,0 +1,6 @@
|
||||
<?php
|
||||
require_once implode(DIRECTORY_SEPARATOR, [
|
||||
dirname(__FILE__, 2),
|
||||
'vendor',
|
||||
'autoload.php'
|
||||
]);
|
9
app/setup/middlewares/99_routes.php
Normal file
9
app/setup/middlewares/99_routes.php
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
$folder = $app->getContainer()->get('folders')->get('routes');
|
||||
$files = new FilesystemIterator($folder);
|
||||
foreach ($files as $file) {
|
||||
if ($file->isDir()) {
|
||||
continue;
|
||||
}
|
||||
include_once $file->getRealPath();
|
||||
}
|
4
app/setup/settings/01_env.php
Normal file
4
app/setup/settings/01_env.php
Normal file
@ -0,0 +1,4 @@
|
||||
<?php
|
||||
return [
|
||||
'logs_folder' => $_ENV['LOGS_PATH'] ?? '/logs'
|
||||
];
|
22
app/setup/settings/02_folders.php
Normal file
22
app/setup/settings/02_folders.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
return [
|
||||
'folders' => function() {
|
||||
return new DI\Container([
|
||||
'base' => dirname(__FILE__, 3),
|
||||
'resources' => DI\String('{base}/resources'),
|
||||
'routes' => DI\String('{resources}/routes'),
|
||||
'cache' => DI\String('{base}/cache'),
|
||||
'templates' => DI\String('{resources}/views')
|
||||
]);
|
||||
/*$arr = ['base' => dirname(__FILE__, 3)];
|
||||
$arr['resources'] = implode(DIRECTORY_SEPARATOR, [
|
||||
$arr['base'],
|
||||
'resources'
|
||||
]);
|
||||
$arr['routes'] = implode(DIRECTORY_SEPARATOR, [
|
||||
$arr['resources'],
|
||||
'routes'
|
||||
]);
|
||||
return (object) $arr;*/
|
||||
}
|
||||
];
|
11
app/setup/settings/03_urls.php
Normal file
11
app/setup/settings/03_urls.php
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
return [
|
||||
'urls' => function() {
|
||||
$arr = ['base' => $_ENV['WEB_URL'] ?? 'http://localhost:' . ($_ENV['WEB_PORT'] ?? 8030)];
|
||||
$arr['assets'] = implode('/', [
|
||||
$arr['base'],
|
||||
'assets'
|
||||
]);
|
||||
return (object) $arr;
|
||||
}
|
||||
];
|
16
app/setup/setups/01_logs.php
Normal file
16
app/setup/setups/01_logs.php
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
return [
|
||||
Psr\Log\LoggerInterface::class => function(ContainerInterface $container) {
|
||||
$logger = new Monolog\Logger('logger');
|
||||
$logger->pushHandler(
|
||||
new Monolog\Handler\RotatingFileHandler(
|
||||
implode(DIRECTORY_SEPARATOR, [
|
||||
$container->get('logs_folder'), 'php.log'
|
||||
])
|
||||
)
|
||||
);
|
||||
return $logger;
|
||||
}
|
||||
];
|
15
app/setup/setups/02_view.php
Normal file
15
app/setup/setups/02_view.php
Normal file
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
return [
|
||||
Slim\Views\Blade::class => function(ContainerInterface $container) {
|
||||
return new Slim\Views\Blade(
|
||||
$container->get('folders')->get('templates'),
|
||||
$container->get('folders')->get('cache'),
|
||||
null,
|
||||
[
|
||||
'urls' => $container->get('urls')
|
||||
]
|
||||
);
|
||||
}
|
||||
];
|
10
app/setup/setups/03_services.php
Normal file
10
app/setup/setups/03_services.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
return [
|
||||
ProVM\Common\Service\Logs::class => function(ContainerInterface $container) {
|
||||
return new ProVM\Common\Service\Logs(
|
||||
$container->get('logs_folder')
|
||||
);
|
||||
}
|
||||
];
|
156
app/src/Log.php
Normal file
156
app/src/Log.php
Normal file
@ -0,0 +1,156 @@
|
||||
<?php
|
||||
namespace ProVM\Logview;
|
||||
|
||||
use DateTimeInterface;
|
||||
use DateTimeImmutable;
|
||||
|
||||
class Log
|
||||
{
|
||||
protected DateTimeInterface $dateTime;
|
||||
protected string $channel;
|
||||
protected string $severity;
|
||||
protected string $message;
|
||||
protected array $stack;
|
||||
protected string $context;
|
||||
protected string $extra;
|
||||
|
||||
public function getDate(): DateTimeInterface
|
||||
{
|
||||
return $this->dateTime;
|
||||
}
|
||||
public function getChannel(): string
|
||||
{
|
||||
return $this->channel;
|
||||
}
|
||||
public function getSeverity(): string
|
||||
{
|
||||
return $this->severity;
|
||||
}
|
||||
public function getMessage(): string
|
||||
{
|
||||
return $this->message;
|
||||
}
|
||||
public function getStack(): array
|
||||
{
|
||||
return $this->stack ?? [];
|
||||
}
|
||||
public function getContext(): string
|
||||
{
|
||||
return $this->context;
|
||||
}
|
||||
public function getExtra(): string
|
||||
{
|
||||
return $this->extra ?? '';
|
||||
}
|
||||
|
||||
public function setDate(DateTimeInterface $dateTime): Log
|
||||
{
|
||||
$this->dateTime = $dateTime;
|
||||
return $this;
|
||||
}
|
||||
public function setChannel(string $channel): Log
|
||||
{
|
||||
$this->channel = $channel;
|
||||
return $this;
|
||||
}
|
||||
public function setSeverity(string $severity): Log
|
||||
{
|
||||
$this->severity = $severity;
|
||||
return $this;
|
||||
}
|
||||
public function setMessage(string $message): Log
|
||||
{
|
||||
$this->message = $message;
|
||||
return $this;
|
||||
}
|
||||
public function setStack(array $stack): Log
|
||||
{
|
||||
$this->stack = $stack;
|
||||
return $this;
|
||||
}
|
||||
public function setContext(string $context): Log
|
||||
{
|
||||
$this->context = $context;
|
||||
return $this;
|
||||
}
|
||||
public function setExtra(string $extra): Log
|
||||
{
|
||||
$this->extra = $extra;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function hasStack(): bool
|
||||
{
|
||||
return isset($this->stack);
|
||||
}
|
||||
public function hasContext(): bool
|
||||
{
|
||||
return $this->context !== '';
|
||||
}
|
||||
|
||||
public function getColor(): string
|
||||
{
|
||||
return self::COLORS[strtoupper($this->getSeverity())];
|
||||
}
|
||||
public function getBackgroundColor(): string
|
||||
{
|
||||
return self::BACKGROUNDS[strtoupper($this->getSeverity())];
|
||||
}
|
||||
|
||||
public static function parse(string $content): Log
|
||||
{
|
||||
$log = new Log();
|
||||
|
||||
$regex = "/\[(?P<date>.*)\]\s(?<channel>\w*)\.(?<severity>\w*):\s(?<message>.*)\s[\[|\{](?<context>.*)[\]|\}]\s\[(?<extra>.*)\]/";
|
||||
preg_match($regex, $content, $matches);
|
||||
$log->setDate(DateTimeImmutable::createFromFormat('Y-m-d\TH:i:s.uP', $matches['date']));
|
||||
$log->setChannel($matches['channel']);
|
||||
$log->setSeverity($matches['severity']);
|
||||
$message = $matches['message'];
|
||||
if (str_contains($message, 'Stack trace')) {
|
||||
list($msg, $data) = explode('Stack trace:', $message);
|
||||
$message = trim($msg);
|
||||
$regex = '/\s#\d+\s/';
|
||||
$lines = preg_split($regex, $data);
|
||||
array_shift($lines);
|
||||
$log->setStack($lines);
|
||||
}
|
||||
$log->setMessage($message);
|
||||
$log->setContext($matches['context']);
|
||||
if (isset($matches['extra'])) {
|
||||
$log->setExtra($matches['extra']);
|
||||
}
|
||||
return $log;
|
||||
}
|
||||
|
||||
const LEVELS = [
|
||||
'DEBUG',
|
||||
'INFO',
|
||||
'NOTICE',
|
||||
'WARNING',
|
||||
'ERROR',
|
||||
'CRITICAL',
|
||||
'ALERT',
|
||||
'EMERGENCY',
|
||||
];
|
||||
const COLORS = [
|
||||
'DEBUG' => '#000',
|
||||
'INFO' => '#000',
|
||||
'NOTICE' => '#fff',
|
||||
'WARNING' => '#000',
|
||||
'ERROR' => '#fff',
|
||||
'CRITICAL' => '#fff',
|
||||
'ALERT' => '#fff',
|
||||
'EMERGENCY' => '#fff',
|
||||
];
|
||||
const BACKGROUNDS = [
|
||||
'DEBUG' => '#fff',
|
||||
'INFO' => '#00f',
|
||||
'NOTICE' => '#55f',
|
||||
'WARNING' => '#dd5',
|
||||
'ERROR' => '#555',
|
||||
'CRITICAL' => '#f00',
|
||||
'ALERT' => '#f55',
|
||||
'EMERGENCY' => '#f55',
|
||||
];
|
||||
}
|
44
app/src/Log/File.php
Normal file
44
app/src/Log/File.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
namespace ProVM\Logview\Log;
|
||||
|
||||
use Generator;
|
||||
use ProVM\Logview\Log;
|
||||
|
||||
class File
|
||||
{
|
||||
protected string $filename;
|
||||
protected string $content;
|
||||
|
||||
public function getFilename(): string
|
||||
{
|
||||
return $this->filename;
|
||||
}
|
||||
public function getContent(): string
|
||||
{
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
public function setFilename(string $filename): File
|
||||
{
|
||||
$this->filename = $filename;
|
||||
return $this;
|
||||
}
|
||||
public function setContent(string $content): File
|
||||
{
|
||||
$this->content = $content;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getLogs(): array
|
||||
{
|
||||
$lines = explode(PHP_EOL, $this->getContent());
|
||||
$logs = [];
|
||||
foreach ($lines as $line) {
|
||||
if (trim($line) === '') {
|
||||
continue;
|
||||
}
|
||||
$logs []= Log::parse($line);
|
||||
}
|
||||
return array_reverse($logs);
|
||||
}
|
||||
}
|
23
docker-compose.yml
Normal file
23
docker-compose.yml
Normal file
@ -0,0 +1,23 @@
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
proxy:
|
||||
container_name: lv_proxy
|
||||
profiles:
|
||||
- app
|
||||
image: nginx
|
||||
ports:
|
||||
- "${WEB_PORT:-8030}:80"
|
||||
volumes:
|
||||
- "./nginx.conf:/etc/nginx/conf.d/default.conf"
|
||||
- "./src:/app"
|
||||
- "./logs:/logs"
|
||||
|
||||
php:
|
||||
container_name: lv_app
|
||||
profiles:
|
||||
- app
|
||||
build: .
|
||||
volumes:
|
||||
- "./src:/app"
|
||||
- "./logs:/logs"
|
22
nginx.conf
Normal file
22
nginx.conf
Normal file
@ -0,0 +1,22 @@
|
||||
server {
|
||||
listen 80;
|
||||
|
||||
error_log /logs/error.log;
|
||||
access_log /logs/access.log;
|
||||
root /app/public;
|
||||
|
||||
location / {
|
||||
try_files $uri /index.php$is_args$args;
|
||||
}
|
||||
|
||||
location ~ \.php {
|
||||
try_files $uri =404;
|
||||
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||
include fastcgi_params;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
|
||||
fastcgi_index index.php;
|
||||
fastcgi_read_timeout 3600;
|
||||
fastcgi_pass php:9000;
|
||||
}
|
||||
}
|
3
php-errors.ini
Normal file
3
php-errors.ini
Normal file
@ -0,0 +1,3 @@
|
||||
display_errors=no
|
||||
log_errors=yes
|
||||
error_log=/logs/php_errors.log
|
Reference in New Issue
Block a user