From 334ffc15b1c2e8ed50df012ae7b37876f7d18128 Mon Sep 17 00:00:00 2001 From: andig Date: Sun, 14 Apr 2024 09:50:08 +0200 Subject: [PATCH] Log Viewer: Allow retrieving logs from ring buffer (#13330) --- assets/css/app.css | 52 ++- assets/js/auth.js | 11 +- assets/js/components/Config/GeneralConfig.vue | 49 ++- assets/js/components/HelpModal.vue | 25 +- assets/js/components/LoginModal.vue | 41 +- assets/js/components/MaterialIcon/Play.vue | 17 + assets/js/components/MaterialIcon/Record.vue | 17 + assets/js/components/Notifications.vue | 8 +- assets/js/components/OfflineIndicator.vue | 14 +- assets/js/components/Savings.vue | 10 +- assets/js/components/TelemetrySettings.vue | 9 +- assets/js/components/TopHeader.vue | 16 +- assets/js/components/TopNavigation.vue | 6 +- assets/js/i18n.js | 6 + assets/js/router.js | 29 +- assets/js/views/App.vue | 17 +- assets/js/views/Config.vue | 359 ++++++++++-------- assets/js/views/Log.vue | 321 ++++++++++++++++ assets/js/views/Main.vue | 16 +- .../js/{components => views}/StartupError.vue | 13 +- cmd/root.go | 15 +- core/keys/site.go | 1 + core/site.go | 1 + i18n/de.toml | 34 +- i18n/en.toml | 31 +- server/http.go | 46 ++- server/http_site_handler.go | 34 ++ tests/auth.spec.js | 19 +- tests/config.spec.js | 26 +- tests/evcc.js | 5 +- tests/logs.spec.js | 49 +++ tests/modals.spec.js | 31 +- util/auth/auth.go | 18 - util/auth/auth_test.go | 4 - util/log.go | 42 +- util/logstash/element.go | 25 ++ util/logstash/levels.go | 27 ++ util/logstash/log.go | 110 ++++++ util/logstash/log_test.go | 33 ++ util/monitor.go | 1 + 40 files changed, 1231 insertions(+), 357 deletions(-) create mode 100644 assets/js/components/MaterialIcon/Play.vue create mode 100644 assets/js/components/MaterialIcon/Record.vue create mode 100644 assets/js/views/Log.vue rename assets/js/{components => views}/StartupError.vue (92%) create mode 100644 tests/logs.spec.js create mode 100644 util/logstash/element.go create mode 100644 util/logstash/levels.go create mode 100644 util/logstash/log.go create mode 100644 util/logstash/log_test.go diff --git a/assets/css/app.css b/assets/css/app.css index 05c212c288..15893d6e99 100644 --- a/assets/css/app.css +++ b/assets/css/app.css @@ -31,6 +31,8 @@ --evcc-dark-yellow: #bbb400; --evcc-orange: #ff9000; --evcc-orange-rgb: 255, 144, 0; + --evcc-red: #fc440f; + --evcc-red-rgb: 252, 68, 15; --bs-gray-deep: #010322; --bs-gray-dark: #28293e; --bs-gray-medium: #93949e; @@ -63,12 +65,16 @@ --bs-warning: var(--evcc-orange); --bs-warning-rgb: var(--evcc-orange-rgb); + --bs-danger: var(--evcc-red); + --bs-danger-rgb: var(--evcc-red-rgb); + --bs-body-font-size: 14px; --bs-font-sans-serif: Montserrat, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; --bs-success: var(--evcc-primary); --bs-success-rgb: var(--bs-primary-rgb); + --bs-code-color: var(--evcc-darkest-green); } :root.dark { @@ -82,6 +88,8 @@ --evcc-accent3: var(--evcc-darker-green); --bs-primary: var(--evcc-dark-green); --bs-border-color-translucent: rgba(255, 255, 255, 0.175); + --bs-code-color: var(--evcc-dark-green); + color-scheme: dark; } html { @@ -229,11 +237,20 @@ a:hover { --bs-btn-line-height: 2; } +.btn-outline-secondary { + --bs-btn-color: var(--evcc-default-text); + --bs-btn-border-color: var(--evcc-default-text); + --bs-btn-hover-bg: transparent; + --bs-btn-hover-color: var(--bs-gray-medium); + --bs-btn-hover-border-color: var(--bs-gray-medium); +} + .dark .btn-outline-secondary { --bs-btn-color: var(--bs-gray-bright); --bs-btn-border-color: var(--bs-gray-bright); - --bs-btn-hover-bg: var(--bs-gray-bright); - --bs-btn-hover-color: var(--bs-gray-dark); + --bs-btn-hover-bg: transparent; + --bs-btn-hover-color: var(--bs-gray-medium); + --bs-btn-hover-border-color: var(--bs-gray-medium); } .accordion { @@ -298,6 +315,9 @@ a:hover { .modal-xl { --bs-modal-width: 850px; } + .w-lg-auto { + width: auto !important; + } } .modal-backdrop.show { @@ -376,6 +396,10 @@ small { background-color: var(--bs-primary); color: var(--bs-white); } +.form-select { + overflow: hidden; + text-overflow: ellipsis; +} .dark .dropdown-menu { box-shadow: 0 0 8px var(--evcc-background); @@ -398,6 +422,7 @@ small { --bs-table-color: var(--evcc-default-text); --bs-table-border-color: var(--evcc-gray); } + .nav-tabs .nav-link { color: var(--evcc-gray) !important; } @@ -438,13 +463,21 @@ input::-webkit-datetime-edit { } .form-control { - background-color: var(--evcc-box); color: var(--evcc-default-text); } .form-control:disabled { color: var(--bs-gray-dark); } +.dark .form-control { + background-color: var(--evcc-box); + color: var(--evcc-default-text); +} + +.dark .form-control::placeholder { + color: var(--bs-gray-medium); +} + input[type="time"]::-webkit-calendar-picker-indicator { display: none; } @@ -515,3 +548,16 @@ html.app .modal-dialog { .btn-neutral:hover { outline: revert; } + +.round-box { + border-radius: 1rem; + box-shadow: 0 0 0 0 var(--evcc-gray-50); + color: var(--evcc-default-text); + background: var(--evcc-box); + padding: 1rem; + border: 1px solid var(--evcc-gray-50); + transition: box-shadow var(--evcc-transition-fast) linear; +} +.round-box:hover { + border-color: var(--evcc-gray); +} diff --git a/assets/js/auth.js b/assets/js/auth.js index ba85b006db..054c0aa8b7 100644 --- a/assets/js/auth.js +++ b/assets/js/auth.js @@ -5,6 +5,7 @@ import Modal from "bootstrap/js/dist/modal"; const auth = reactive({ configured: true, loggedIn: false, + nextUrl: null, }); export async function updateAuthStatus() { @@ -28,6 +29,7 @@ export async function logout() { try { await api.post("/auth/logout"); await updateAuthStatus(); + auth.nextUrl = null; } catch (e) { console.log("unable to logout", e); } @@ -41,7 +43,14 @@ export function isConfigured() { return auth.configured; } -export function openLoginModal() { +export function getAndClearNextUrl() { + const nextUrl = auth.nextUrl; + auth.nextUrl = null; + return nextUrl; +} + +export function openLoginModal(nextUrl = null) { + auth.nextUrl = nextUrl; const modal = Modal.getOrCreateInstance(document.getElementById("loginModal")); modal.show(); } diff --git a/assets/js/components/Config/GeneralConfig.vue b/assets/js/components/Config/GeneralConfig.vue index ee4eba811e..6b90345de7 100644 --- a/assets/js/components/Config/GeneralConfig.vue +++ b/assets/js/components/Config/GeneralConfig.vue @@ -1,5 +1,5 @@ @@ -16,10 +13,11 @@ import "@h2d2/shopicons/es/regular/cloud"; export default { name: "OfflineIndicator", - methods: { - reload() { - window.location.reload(); - }, - }, }; + diff --git a/assets/js/components/Savings.vue b/assets/js/components/Savings.vue index 21fb7d46f4..324cd3b952 100644 --- a/assets/js/components/Savings.vue +++ b/assets/js/components/Savings.vue @@ -171,11 +171,7 @@
- + {{ $t("footer.savings.configurePriceCo2") }}
@@ -206,6 +202,7 @@ import CustomSelect from "./CustomSelect.vue"; import co2Reference from "../co2Reference"; import settings from "../settings"; import api from "../api"; +import { docsPrefix } from "../i18n"; export default { name: "Savings", @@ -227,6 +224,9 @@ export default { }; }, computed: { + tariffLink() { + return `${docsPrefix()}/docs/reference/configuration/tariffs`; + }, percent() { return Math.round(this.solarPercentage) || 0; }, diff --git a/assets/js/components/TelemetrySettings.vue b/assets/js/components/TelemetrySettings.vue index e8dc7c1e74..3201bd69c3 100644 --- a/assets/js/components/TelemetrySettings.vue +++ b/assets/js/components/TelemetrySettings.vue @@ -14,10 +14,7 @@