Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Long log format #424

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@
/composer.phar
/composer.lock
/phpunit.xml
/.vscode
.DS_Store
Thumbs.db
.phpunit.result.cache
27 changes: 20 additions & 7 deletions constants.php
Original file line number Diff line number Diff line change
@@ -1,21 +1,34 @@
<?php

if ( ! defined('REGEX_DATE_PATTERN')) {
define('REGEX_DATE_PATTERN', '\d{4}(-\d{2}){2}'); // YYYY-MM-DD
if (! defined('REGEX_DATE_PATTERN')) {
define('REGEX_DATE_PATTERN', '\d{4}(?:-\d{2}){2}'); // YYYY-MM-DD
}

if ( ! defined('REGEX_TIME_PATTERN')) {
define('REGEX_TIME_PATTERN', '\d{2}(:\d{2}){2}'); // HH:MM:SS
if (! defined('REGEX_TIME_PATTERN')) {
define('REGEX_TIME_PATTERN', '\d{2}(?::\d{2}){2}'); // HH:MM:SS
}

if ( ! defined('REGEX_DATETIME_PATTERN')) {
if (! defined('REGEX_DATETIME_SEPARATOR')) {
define('REGEX_DATETIME_SEPARATOR', '([T ])');
}

if (! defined('REGEX_MS_PATTERN')) {
define('REGEX_MS_PATTERN', '(\.\d{6})?'); // .uuuuuu
}

if (! defined('REGEX_TIMEZONE_PATTERN')) {
define('REGEX_TIMEZONE_PATTERN', '([-+]\d{2}:\d{2})?'); // +ZZ:ZZ
}

if (! defined('REGEX_DATETIME_PATTERN')) {
define(
'REGEX_DATETIME_PATTERN',
REGEX_DATE_PATTERN . ' ' . REGEX_TIME_PATTERN // YYYY-MM-DD HH:MM:SS
// YYYY-MM-DDTHH:MM:SS.uuuuuu+ZZ:ZZ
REGEX_DATE_PATTERN . REGEX_DATETIME_SEPARATOR . REGEX_TIME_PATTERN . REGEX_MS_PATTERN . REGEX_TIMEZONE_PATTERN
);
}

// Fix undefined constant GLOB_BRACE exception on Alpine Linux (https://bugs.php.net/bug.php?id=72095)
if ( ! defined('GLOB_BRACE')) {
if (! defined('GLOB_BRACE')) {
define('GLOB_BRACE', 0);
}
12 changes: 6 additions & 6 deletions helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use Arcanedev\LogViewer\Contracts;

if ( ! function_exists('log_viewer')) {
if (!function_exists('log_viewer')) {
/**
* Get the LogViewer instance.
*
Expand All @@ -14,7 +14,7 @@ function log_viewer()
}
}

if ( ! function_exists('log_levels')) {
if (!function_exists('log_levels')) {
/**
* Get the LogLevels instance.
*
Expand All @@ -26,7 +26,7 @@ function log_levels()
}
}

if ( ! function_exists('log_menu')) {
if (!function_exists('log_menu')) {
/**
* Get the LogMenu instance.
*
Expand All @@ -38,7 +38,7 @@ function log_menu()
}
}

if ( ! function_exists('log_styler')) {
if (!function_exists('log_styler')) {
/**
* Get the LogStyler instance.
*
Expand All @@ -50,7 +50,7 @@ function log_styler()
}
}

if ( ! function_exists('extract_date')) {
if (!function_exists('extract_date')) {
/**
* Extract date from string (format : YYYY-MM-DD).
*
Expand All @@ -60,6 +60,6 @@ function log_styler()
*/
function extract_date($string)
{
return preg_replace('/.*('.REGEX_DATE_PATTERN.').*/', '$1', $string);
return preg_replace('/.*(' . REGEX_DATE_PATTERN . ').*/', '$1', $string);
}
}
41 changes: 27 additions & 14 deletions src/Entities/LogEntry.php
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
<?php namespace Arcanedev\LogViewer\Entities;
<?php

namespace Arcanedev\LogViewer\Entities;

use Carbon\Carbon;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Contracts\Support\Jsonable;
use JsonSerializable;
use LogicException;

/**
* Class LogEntry
Expand Down Expand Up @@ -83,7 +86,7 @@ private function setLevel($level)
*/
private function setHeader($header)
{
$this->setDatetime($this->extractDatetime($header));
$this->setDatetime(...$this->extractDatetime($header));

$header = $this->cleanHeader($header);

Expand Down Expand Up @@ -115,21 +118,22 @@ private function setContext(array $context)
*/
private function setEnv($env)
{
$this->env = head(explode('.', $env));
$this->env = $env;

return $this;
}

/**
* Set the entry date time.
*
* @param string $format
* @param string $datetime
*
* @return \Arcanedev\LogViewer\Entities\LogEntry
*/
private function setDatetime($datetime)
private function setDatetime($format, $datetime)
{
$this->datetime = Carbon::createFromFormat('Y-m-d H:i:s', $datetime);
$this->datetime = Carbon::createFromFormat($format, $datetime);

return $this;
}
Expand All @@ -155,7 +159,7 @@ private function setStack($stack)
*/
public function level()
{
return $this->icon()->toHtml().' '.$this->name();
return $this->icon()->toHtml() . ' ' . $this->name();
}

/**
Expand Down Expand Up @@ -279,7 +283,7 @@ public function hasStack()
*/
public function hasContext()
{
return ! empty($this->context);
return !empty($this->context);
}

/* -----------------------------------------------------------------
Expand All @@ -297,17 +301,18 @@ public function hasContext()
private function cleanHeader($header)
{
// REMOVE THE DATE
$header = preg_replace('/\['.REGEX_DATETIME_PATTERN.'\][ ]/', '', $header);
$header = preg_replace('/\[' . REGEX_DATETIME_PATTERN . '\]/', '', $header);

// EXTRACT ENV
if (preg_match('/^[a-z]+.[A-Z]+:/', $header, $out)) {
$this->setEnv($out[0]);
$header = trim(str_replace($out[0], '', $header));
$regex = '/.* ([a-z]+)\.[A-Z]+:/';
if (preg_match_all($regex, $header, $out)) {
$this->setEnv($out[1][0] ?? null);
$header = preg_replace($regex, '', $header);
}

// EXTRACT CONTEXT (Regex from https://stackoverflow.com/a/21995025)
preg_match_all('/{(?:[^{}]|(?R))*}/x', $header, $out);
if (isset($out[0][0]) && ! is_null($context = json_decode($out[0][0], true))) {
if (isset($out[0][0]) && !is_null($context = json_decode($out[0][0], true))) {
$header = str_replace($out[0][0], '', $header);
$this->setContext($context);
}
Expand All @@ -320,10 +325,18 @@ private function cleanHeader($header)
*
* @param string $header
*
* @return string
* @return array
*/
private function extractDatetime($header)
{
return preg_replace('/^\[('.REGEX_DATETIME_PATTERN.')\].*/', '$1', $header);
if (preg_match_all('/^\[(' . REGEX_DATETIME_PATTERN . ')\].*/', $header, $matches)) {
$separator = ($matches[2][0] ?? null) === 'T' ? '\T' : ' ';
$ms = ($matches[3][0] ?? null) ? '.u' : '';
$tz = ($matches[4][0] ?? null) ? 'P' : '';
$format = "Y-m-d{$separator}H:i:s{$ms}{$tz}";
$datetime = $matches[1][0];
return [$format, $datetime];
}
return [];
}
}
8 changes: 5 additions & 3 deletions src/Helpers/LogParser.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<?php namespace Arcanedev\LogViewer\Helpers;
<?php

namespace Arcanedev\LogViewer\Helpers;

use Arcanedev\LogViewer\Utilities\LogLevels;
use Illuminate\Support\Str;
Expand Down Expand Up @@ -41,7 +43,7 @@ public static function parse($raw)
list($headings, $data) = self::parseRawData($raw);

// @codeCoverageIgnoreStart
if ( ! is_array($headings)) {
if (! is_array($headings)) {
return self::$parsed;
}
// @codeCoverageIgnoreEnd
Expand Down Expand Up @@ -71,7 +73,7 @@ public static function parse($raw)
*/
private static function parseRawData($raw)
{
$pattern = '/\['.REGEX_DATE_PATTERN.' '.REGEX_TIME_PATTERN.'\].*/';
$pattern = '/\[' . REGEX_DATETIME_PATTERN . '\].*/';
preg_match_all($pattern, $raw, $headings);
$data = preg_split($pattern, $raw);

Expand Down
8 changes: 4 additions & 4 deletions tests/Entities/LogCollectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ public function it_can_be_instantiated()
/** @test */
public function it_can_get_all_logs()
{
static::assertCount(2, $this->logs);
static::assertSame(2, $this->logs->count());
static::assertSame(16, $this->logs->total());
static::assertCount(3, $this->logs);
static::assertSame(3, $this->logs->count());
static::assertSame(24, $this->logs->total());

foreach ($this->logs as $date => $log) {
/** @var \Arcanedev\LogViewer\Entities\Log $log */
Expand Down Expand Up @@ -137,7 +137,7 @@ public function it_can_get_log_tree()
{
$tree = $this->logs->tree();

static::assertCount(2, $tree);
static::assertCount(3, $tree);

foreach ($tree as $date => $levels) {
static::assertDate($date);
Expand Down
20 changes: 10 additions & 10 deletions tests/LogViewerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,20 +58,20 @@ public function it_can_be_instantiated_with_helper()
/** @test */
public function it_can_get_logs_count()
{
static::assertSame(2, $this->logViewer->count());
static::assertSame(3, $this->logViewer->count());
}

/** @test */
public function it_can_get_entries_total()
{
static::assertSame(16, $this->logViewer->total());
static::assertSame(24, $this->logViewer->total());
}

/** @test */
public function it_can_get_entries_total_by_level()
{
foreach (self::$logLevels as $level) {
static::assertSame(2, $this->logViewer->total($level));
static::assertSame(3, $this->logViewer->total($level));
}
}

Expand All @@ -80,8 +80,8 @@ public function it_can_get_all_logs()
{
$logs = $this->logViewer->all();

static::assertCount(2, $logs);
static::assertSame(2, $logs->count());
static::assertCount(3, $logs);
static::assertSame(3, $logs->count());

foreach ($logs as $log) {
/** @var Log $log */
Expand All @@ -101,7 +101,7 @@ public function it_can_paginate_all_logs()

static::assertInstanceOf(\Illuminate\Pagination\LengthAwarePaginator::class, $logs);
static::assertSame(30, $logs->perPage());
static::assertSame(2, $logs->total());
static::assertSame(3, $logs->total());
static::assertSame(1, $logs->lastPage());
static::assertSame(1, $logs->currentPage());
}
Expand Down Expand Up @@ -158,7 +158,7 @@ public function it_can_get_log_dates()
{
$dates = $this->logViewer->dates();

static::assertCount(2, $dates);
static::assertCount(3, $dates);
static::assertDates($dates);
}

Expand All @@ -167,7 +167,7 @@ public function it_can_get_log_files()
{
$files = $this->logViewer->files();

static::assertCount(2, $files);
static::assertCount(3, $files);
foreach ($files as $file) {
static::assertFileExists($file);
}
Expand Down Expand Up @@ -228,7 +228,7 @@ public function it_can_get_tree()
{
$tree = $this->logViewer->tree();

static::assertCount(2, $tree);
static::assertCount(3, $tree);

foreach ($tree as $date => $counters) {
static::assertDate($date);
Expand All @@ -254,7 +254,7 @@ public function it_can_get_translated_menu()
$this->app->setLocale($locale);
$menu = $this->logViewer->menu();

static::assertCount(2, $menu);
static::assertCount(3, $menu);

foreach ($menu as $date => $counters) {
static::assertDate($date);
Expand Down
2 changes: 1 addition & 1 deletion tests/Tables/StatsTableTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ protected static function assertTableRows(TableContract $table)
protected static function assertTableFooter(TableContract $table)
{
foreach ($table->footer() as $key => $value) {
self::assertEquals($key === 'all' ? 16 : 2, $value);
self::assertEquals($key === 'all' ? 24 : 3, $value);
}
}

Expand Down
Loading