Skip to content

Commit

Permalink
add basic logger
Browse files Browse the repository at this point in the history
  • Loading branch information
michnhokn committed Nov 10, 2021
1 parent 1c88ca1 commit c71f75d
Show file tree
Hide file tree
Showing 9 changed files with 301 additions and 70 deletions.
1 change: 1 addition & 0 deletions index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
table{width:100%;border-collapse:collapse}table td,table th{padding:6px 12px;text-align:left;border:1px solid var(--color-border)}
25 changes: 11 additions & 14 deletions index.js

Large diffs are not rendered by default.

61 changes: 17 additions & 44 deletions index.php
Original file line number Diff line number Diff line change
@@ -1,45 +1,18 @@
<?php

require_once __DIR__ . '/src/Logger.php';

\Kirby\Cms\App::plugin('michnhokn/logger', [
'hooks' => [
'*:before' => function (\Kirby\Cms\Event $event) {
$type = $event->type();
$action = $event->action();
}
],
'routes' => [
[
'pattern' => 'db',
'action' => function () {
$logDir = kirby()->root('logs') . '/kirby3-logger/';
\Kirby\Filesystem\Dir::make($logDir, true);
$database = new \Kirby\Database\Database([
'type' => 'sqlite',
'database' => $logDir . 'logs.sqlite'
]);
$schema = \Kirby\Filesystem\F::read(__DIR__ . '/logs-schema.sql');
$database->execute($schema);
dump(
$database->table('logs')->insert([
'type' => 'test',
'action' => 'action',
'userId' => 'userId',
'oldValue' => 'oldValue',
'currentValue' => 'currentValue',
])
);
die;
}
],
'system.loadPlugins:after' => function () {
Logger::connect();
},
'*:after' => function (\Kirby\Cms\Event $event) {
Logger::log($event);
},
],
'areas' => [
'kirby3-logger' => function ($kirby) {
$logDir = kirby()->root('logs') . '/kirby3-logger/';
$database = new \Kirby\Database\Database([
'type' => 'sqlite',
'database' => $logDir . 'logs.sqlite'
]);

return [
'label' => 'Logger',
'icon' => 'table',
Expand All @@ -48,18 +21,18 @@
'views' => [
[
'pattern' => 'logger',
'action' => function () use ($database) {
'action' => function () {
return [
'component' => 'k-logger-view',
'component' => 'k-logger-area',
'title' => 'Logs',
'props' => [
'logs' => $database->table('logs')->all()
]
'logs' => Logger::logs(),
],
];
}
]
]
},
],
],
];
}
]
},
],
]);
20 changes: 8 additions & 12 deletions logs-schema.sql
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
CREATE TABLE IF NOT EXISTS logs
(
id INTEGER PRIMARY KEY,
type TEXT NOT NULL,
action TEXT NOT NULL,
userId TEXT NULL,
oldValue TEXT NULL,
currentValue TEXT NOT NULL,
timestamp TEXT NOT NULL DEFAULT current_timestamp
);

CREATE INDEX index_users ON logs (userId);
CREATE INDEX index_actions ON logs (action);
CREATE INDEX index_types ON logs (type);
id INTEGER PRIMARY KEY,
type TEXT NOT NULL,
action TEXT NOT NULL,
user TEXT NULL,
old TEXT NOT NULL,
new TEXT NOT NULL,
timestamp TEXT NOT NULL DEFAULT current_timestamp
);
92 changes: 92 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"scripts": {
"dev": "npx -y kirbyup src/index.js --watch",
"build": "npx -y kirbyup src/index.js"
},
"dependencies": {
"fuse.js": "^6.4.6",
"vue-json-component": "^0.4.1",
"vue-json-pretty": "^1.8.2",
"vue-json-tree-view": "^2.1.6"
}
}
75 changes: 75 additions & 0 deletions src/Logger.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php

use Kirby\Cms\Event;
use Kirby\Database\Database;
use Kirby\Filesystem\Dir;
use Kirby\Filesystem\F;

class Logger
{
const TYPES = ['file', 'page', 'user', 'site'];

/**
* The singleton Database object
*
* @var Database
*/
public static $connection = null;

/**
* Connect the database
*
* @return Database
* @throws Exception
*/
public static function connect(): ?Database
{
if (static::$connection !== null) {
return static::$connection;
}
$logDir = kirby()->root('logs') . '/kirby3-logger/';
$schema = F::read(__DIR__ . '/../logs-schema.sql');

Dir::make($logDir, true);

static::$connection = new Database(['type' => 'sqlite', 'database' => $logDir . 'logs.sqlite']);
if (!self::$connection->validateTable('logs')) {
self::$connection->execute($schema);
}

return self::$connection;
}

public static function logs()
{
return self::$connection->table('logs')->select('*')->all();
}

public static function log(Event $event)
{
if (!in_array($event->type(), self::TYPES)) {
return;
}

$args = self::getArguments($event);
self::$connection->table('logs')->insert([
'type' => $event->type(),
'action' => $event->action(),
'user' => kirby()->user()->email(),
'old' => $args[0] ?? '-',
'new' => $args[1] ?? '-',
]);
}

private static function getArguments(Event $event)
{
switch ($event->type()) {
case 'site':
switch ($event->action()) {
case 'changeTitle':
return [$event->oldSite()->title(), $event->newSite()->title()];
}
break;
}
}
}
80 changes: 80 additions & 0 deletions src/components/LoggerArea.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<template>
<k-inside>
<k-view class="k-logger-view">
<k-header>Logger</k-header>
<k-text-field v-model="searchTerm" name="text" placeholder="Suche" icon="search"/>
<br>
<table class="k-system-plugins">
<thead>
<tr>
<th>Timestamp</th>
<th>User</th>
<th>Type</th>
<th>Action</th>
<th>Old</th>
<th>New</th>
</tr>
</thead>
<tbody>
<tr v-for="log in entries" :key="log.id">
<td>{{ log.timestamp || log.item.timestamp }}</td>
<td>{{ log.user || log.item.user }}</td>
<td>{{ log.type || log.item.type }}</td>
<td>{{ log.action || log.item.action }}</td>
<td>{{ log.old || log.item.old }}</td>
<td>{{ log.new || log.item.new }}</td>
</tr>
</tbody>
</table>

</k-view>
</k-inside>
</template>

<script>
import Fuse from 'fuse.js';
import {JSONView} from 'vue-json-component/dist/index.umd';
export default {
name: 'LoggerArea',
props: ['logs'],
components: {'json-view': JSONView},
data() {
return {
searchTerm: '',
currentArguments: null,
fuse: null,
};
},
computed: {
entries() {
return this.searchTerm ? this.fuse?.search(this.searchTerm) : this.logs?.data;
},
},
mounted() {
this.fuse = new Fuse(this.logs?.data, {
includeScore: true,
keys: ['action', 'type', 'email', 'timestamp'],
});
},
methods: {
showArguments(args) {
this.currentArguments = args;
this.$refs.dialog.open();
},
},
};
</script>
<style lang="scss">
table {
width: 100%;
border-collapse: collapse;
td, th {
padding: 6px 12px;
text-align: left;
border: 1px solid var(--color-border);
}
}
</style>
5 changes: 5 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import LoggerArea from './components/LoggerArea.vue';

window.panel.plugin('michnhokn/logger', {
components: {'k-logger-area': LoggerArea},
});

0 comments on commit c71f75d

Please sign in to comment.