diff --git a/index.html b/index.html index 1a08f58..9c46573 100644 --- a/index.html +++ b/index.html @@ -1,776 +1,1266 @@ + - - -Log Viewer - - - - - + #file-info { + font-family: var(--font-mono); + font-size: 11px; + color: var(--text3); + flex: 1; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis + } + + #file-btn { + display: flex; + align-items: center; + gap: 7px; + background: var(--surface3); + border: 1px solid var(--border2); + border-radius: var(--radius); + color: var(--text2); + font-family: var(--font-sans); + font-size: 12px; + font-weight: 500; + padding: 6px 12px; + cursor: pointer; + transition: all .15s; + white-space: nowrap; + } + + #file-btn:hover { + border-color: var(--border3); + color: var(--text); + background: var(--surface2) + } + + #file-input { + display: none + } + + .hdr-sep { + width: 1px; + height: 20px; + background: var(--border) + } + + /* Filter bar */ + #filter-bar { + display: flex; + align-items: center; + gap: 10px; + padding: 8px 20px; + border-bottom: 1px solid var(--border); + background: var(--surface); + flex-shrink: 0; + } + + #search-wrap { + position: relative; + flex: 1; + max-width: 420px + } + + #search-wrap svg { + position: absolute; + left: 10px; + top: 50%; + transform: translateY(-50%); + opacity: .4; + pointer-events: none + } + + #search { + width: 100%; + background: var(--surface3); + border: 1px solid var(--border2); + border-radius: var(--radius); + color: var(--text); + font-family: var(--font-mono); + font-size: 12px; + padding: 6px 10px 6px 32px; + outline: none; + transition: border-color .15s; + } + + #search:focus { + border-color: var(--accent); + box-shadow: 0 0 0 3px var(--accent-dim) + } + + #search.invalid { + border-color: var(--error); + box-shadow: 0 0 0 3px #e8504a18 + } + + #search::placeholder { + color: var(--text3) + } + + #regex-badge { + position: absolute; + right: 8px; + top: 50%; + transform: translateY(-50%); + font-family: var(--font-mono); + font-size: 10px; + padding: 2px 5px; + border-radius: 3px; + background: var(--accent-dim); + color: var(--accent); + opacity: .7; + } + + /* Level pills */ + .level-pills { + display: flex; + gap: 6px; + flex-wrap: wrap + } + + .level-pill { + display: flex; + align-items: center; + gap: 6px; + padding: 5px 10px; + border-radius: 20px; + border: 1px solid var(--border2); + background: transparent; + cursor: pointer; + font-family: var(--font-sans); + font-size: 11px; + font-weight: 500; + color: var(--text2); + transition: all .15s; + white-space: nowrap; + } + + .level-pill:hover { + border-color: var(--border3); + color: var(--text) + } + + .level-pill.active { + border-color: currentColor + } + + .level-pill[data-level="TRACE"] { + --lc: var(--trace) + } + + .level-pill[data-level="DEBUG"] { + --lc: var(--debug) + } + + .level-pill[data-level="INFO"] { + --lc: var(--info) + } + + .level-pill[data-level="WARN"] { + --lc: var(--warn) + } + + .level-pill[data-level="ERROR"] { + --lc: var(--error) + } + + .level-pill[data-level="FATAL"] { + --lc: var(--fatal) + } + + .level-pill.active { + color: var(--lc); + border-color: var(--lc); + background: color-mix(in srgb, var(--lc) 10%, transparent) + } + + .pill-dot { + width: 6px; + height: 6px; + border-radius: 50%; + background: var(--lc, var(--text3)); + flex-shrink: 0 + } + + .pill-count { + font-family: var(--font-mono); + font-size: 10px; + opacity: .7 + } + + .filter-actions { + display: flex; + gap: 6px; + margin-left: auto + } + + #clear-filters { + padding: 5px 10px; + border-radius: var(--radius); + border: 1px solid var(--border2); + background: transparent; + color: var(--text3); + font-size: 11px; + font-family: var(--font-sans); + cursor: pointer; + transition: all .15s; + } + + #clear-filters:hover { + color: var(--text); + border-color: var(--border3) + } + + #time-badge { + display: none; + align-items: center; + gap: 5px; + padding: 5px 10px; + border-radius: var(--radius); + background: var(--accent-dim); + border: 1px solid var(--accent); + color: var(--accent); + font-size: 11px; + font-family: var(--font-mono); + cursor: pointer; + } + + #time-badge.visible { + display: flex + } + + #time-badge:hover { + background: #4f8ef730 + } + + #time-badge .tx-close { + opacity: .6; + margin-left: 2px + } + + /* Main layout */ + #main { + display: flex; + flex-direction: column; + flex: 1; + overflow: hidden + } + + /* Chart panel */ + #chart-panel { + flex-shrink: 0; + padding: 16px 20px 12px; + border-bottom: 1px solid var(--border); + } + + #chart-wrap { + position: relative; + height: 100px + } + + #chart-hint { + position: absolute; + top: 4px; + right: 0; + font-size: 10px; + color: var(--text3); + font-family: var(--font-mono) + } + + /* Table area */ + #table-area { + flex: 1; + overflow: hidden; + display: flex; + flex-direction: column + } + + /* DataTables custom styles */ + #dt-wrap { + flex: 1; + overflow: auto; + padding: 0 20px 20px + } + + table#log-table { + width: 100%; + border-collapse: collapse; + font-family: var(--font-mono); + font-size: 11.5px + } + + table#log-table thead th { + position: sticky; + top: 0; + z-index: 10; + background: var(--surface); + border-bottom: 1px solid var(--border2); + padding: 10px 12px; + text-align: left; + font-weight: 500; + color: var(--text2); + font-size: 11px; + letter-spacing: .05em; + text-transform: uppercase; + white-space: nowrap; + cursor: pointer; + user-select: none; + } + + table#log-table thead th:hover { + color: var(--text) + } + + table#log-table thead th.sort-asc::after { + content: ' ↑' + } + + table#log-table thead th.sort-desc::after { + content: ' ↓' + } + + table#log-table tbody tr { + border-bottom: 1px solid var(--border); + cursor: pointer; + transition: background .1s + } + + table#log-table tbody tr:hover>td { + background: var(--surface2) + } + + table#log-table tbody td { + padding: 7px 12px; + vertical-align: top + } + + .col-time { + width: 180px; + color: var(--text3); + white-space: nowrap + } + + .col-level { + width: 72px + } + + .col-msg { + word-break: break-word + } + + /* Level badges */ + .lv { + display: inline-block; + padding: 2px 7px; + border-radius: 3px; + font-size: 10px; + font-weight: 500; + letter-spacing: .04em + } + + .lv-TRACE { + background: var(--trace-bg); + color: var(--trace) + } + + .lv-DEBUG { + background: var(--debug-bg); + color: var(--debug) + } + + .lv-INFO { + background: var(--info-bg); + color: var(--info) + } + + .lv-WARN { + background: var(--warn-bg); + color: var(--warn) + } + + .lv-ERROR { + background: var(--error-bg); + color: var(--error) + } + + .lv-FATAL { + background: var(--fatal-bg); + color: var(--fatal) + } + + /* Row details (expanded) */ + .row-detail { + background: var(--surface2) !important; + border-left: 2px solid var(--accent) !important + } + + .row-detail td { + padding: 0 !important + } + + .detail-inner { + padding: 12px 16px 16px; + display: flex; + flex-direction: column; + gap: 12px + } + + .detail-section { + display: flex; + flex-direction: column; + gap: 6px + } + + .detail-label { + font-size: 10px; + font-weight: 500; + letter-spacing: .08em; + text-transform: uppercase; + color: var(--text3) + } + + .detail-val { + background: var(--surface3); + border: 1px solid var(--border); + border-radius: var(--radius); + padding: 10px 12px; + font-family: var(--font-mono); + font-size: 11px; + color: var(--text2); + white-space: pre-wrap; + word-break: break-all; + max-height: 200px; + overflow-y: auto; + line-height: 1.6; + } + + /* Empty state */ + #empty-state { + flex: 1; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 16px; + color: var(--text3); + } + + #empty-state svg { + opacity: .3 + } + + #empty-state .es-title { + font-size: 15px; + font-weight: 500; + color: var(--text2) + } + + #empty-state .es-sub { + font-size: 12px; + text-align: center; + max-width: 280px; + line-height: 1.6 + } + + #empty-state .es-btn { + margin-top: 8px; + padding: 8px 20px; + border-radius: var(--radius); + background: var(--accent-dim); + border: 1px solid var(--accent); + color: var(--accent); + font-size: 13px; + font-family: var(--font-sans); + cursor: pointer; + transition: all .15s; + } + + #empty-state .es-btn:hover { + background: #4f8ef730 + } + + /* Table status bar */ + #status-bar { + display: flex; + align-items: center; + gap: 12px; + padding: 7px 20px; + border-top: 1px solid var(--border); + background: var(--surface); + flex-shrink: 0; + font-size: 11px; + color: var(--text3); + font-family: var(--font-mono); + } + + #status-bar .status-count { + color: var(--text2) + } + + .sb-sep { + color: var(--border3) + } + + /* Scrollbar */ + ::-webkit-scrollbar { + width: 6px; + height: 6px + } + + ::-webkit-scrollbar-track { + background: transparent + } + + ::-webkit-scrollbar-thumb { + background: var(--border2); + border-radius: 3px + } + + ::-webkit-scrollbar-thumb:hover { + background: var(--border3) + } + + /* Animations */ + @keyframes fadeIn { + from { + opacity: 0; + transform: translateY(4px) + } + + to { + opacity: 1; + transform: translateY(0) + } + } + + .fade-in { + animation: fadeIn .2s ease forwards + } + + - -
- - - - -
Drop log file here
-
Supports .log, .txt, .json and plain text
-
- - - - - -
-
- - - .* -
-
-
- - - - - -
-
-
- - time range - -
- -
-
- - -
- -
-
- - drag to zoom · right-click to reset -
-
- - -
- - - + +
+ + + -
No log file loaded
-
Drag & drop a log file anywhere on the page or click below to browse
- +
Drop log file here
+
Supports .log, .txt, .json and plain text
-