├── screenshot.png
├── public
├── favicon.ico
├── robots.txt
├── patterns
│ ├── maven
│ ├── postgresql
│ ├── ruby
│ ├── mcollective
│ ├── redis
│ ├── squid
│ ├── mongodb
│ ├── bind
│ ├── rails
│ ├── linux-syslog
│ ├── httpd
│ ├── junos
│ ├── exim
│ ├── java
│ ├── haproxy
│ ├── bro
│ ├── aws
│ ├── zeek
│ ├── grok-patterns
│ ├── bacula
│ ├── nagios
│ ├── postfix
│ └── firewalls
├── web
│ └── onigasm.wasm
├── favicon_io
│ ├── favicon.ico
│ ├── favicon-16x16.png
│ ├── favicon-32x32.png
│ ├── apple-touch-icon.png
│ ├── android-chrome-192x192.png
│ ├── android-chrome-512x512.png
│ ├── site.webmanifest
│ └── about.txt
├── manifest.json
└── index.html
├── src
├── index.js
├── components
│ ├── Ad.js
│ ├── Navbar.js
│ ├── LoadModal.js
│ ├── ShareModal.js
│ ├── SaveModal.js
│ ├── CustomPatternModal.js
│ └── MorePatternsModal.js
├── codemirror
│ ├── grok.js
│ └── codemirror.css
├── hooks
│ └── useLocalStorage.js
├── index.css
└── App.js
├── .gitignore
├── LICENSE
├── package.json
└── README.md
/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cjslack/grok-debugger/HEAD/screenshot.png
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cjslack/grok-debugger/HEAD/public/favicon.ico
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/public/patterns/maven:
--------------------------------------------------------------------------------
1 | MAVEN_VERSION (?:(\d+)\.)?(?:(\d+)\.)?(\*|\d+)(?:[.-](RELEASE|SNAPSHOT))?
2 |
--------------------------------------------------------------------------------
/public/web/onigasm.wasm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cjslack/grok-debugger/HEAD/public/web/onigasm.wasm
--------------------------------------------------------------------------------
/public/favicon_io/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cjslack/grok-debugger/HEAD/public/favicon_io/favicon.ico
--------------------------------------------------------------------------------
/public/favicon_io/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cjslack/grok-debugger/HEAD/public/favicon_io/favicon-16x16.png
--------------------------------------------------------------------------------
/public/favicon_io/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cjslack/grok-debugger/HEAD/public/favicon_io/favicon-32x32.png
--------------------------------------------------------------------------------
/public/favicon_io/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cjslack/grok-debugger/HEAD/public/favicon_io/apple-touch-icon.png
--------------------------------------------------------------------------------
/public/favicon_io/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cjslack/grok-debugger/HEAD/public/favicon_io/android-chrome-192x192.png
--------------------------------------------------------------------------------
/public/favicon_io/android-chrome-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cjslack/grok-debugger/HEAD/public/favicon_io/android-chrome-512x512.png
--------------------------------------------------------------------------------
/public/patterns/postgresql:
--------------------------------------------------------------------------------
1 | # Default postgresql pg_log format pattern
2 | POSTGRESQL %{DATESTAMP:timestamp} %{TZ:[event][timezone]} %{DATA:[user][name]} %{GREEDYDATA:[postgresql][log][connection_id]} %{POSINT:[process][pid]:int}
3 |
--------------------------------------------------------------------------------
/public/patterns/ruby:
--------------------------------------------------------------------------------
1 | RUBY_LOGLEVEL (?:DEBUG|FATAL|ERROR|WARN|INFO)
2 | RUBY_LOGGER [DFEWI], \[%{TIMESTAMP_ISO8601:timestamp} #%{POSINT:[process][pid]:int}\] *%{RUBY_LOGLEVEL:[log][level]} -- +%{DATA:[process][name]}: %{GREEDYDATA:message}
3 |
--------------------------------------------------------------------------------
/public/patterns/mcollective:
--------------------------------------------------------------------------------
1 | # Remember, these can be multi-line events.
2 | MCOLLECTIVE ., \[%{TIMESTAMP_ISO8601:timestamp} #%{POSINT:[process][pid]:int}\]%{SPACE}%{LOGLEVEL:[log][level]}
3 |
4 | MCOLLECTIVEAUDIT %{TIMESTAMP_ISO8601:timestamp}:
5 |
--------------------------------------------------------------------------------
/public/favicon_io/site.webmanifest:
--------------------------------------------------------------------------------
1 | {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}
--------------------------------------------------------------------------------
/public/patterns/redis:
--------------------------------------------------------------------------------
1 | REDISTIMESTAMP %{MONTHDAY} %{MONTH} %{TIME}
2 | REDISLOG \[%{POSINT:[process][pid]:int}\] %{REDISTIMESTAMP:timestamp} \*
3 | REDISMONLOG %{NUMBER:timestamp} \[%{INT:[redis][database][id]} %{IP:[client][ip]}:%{POSINT:[client][port]:int}\] "%{WORD:[redis][command][name]}"\s?%{GREEDYDATA:[redis][command][args]}
4 |
--------------------------------------------------------------------------------
/public/favicon_io/about.txt:
--------------------------------------------------------------------------------
1 | This favicon was generated using the following font:
2 |
3 | - Font Title: Roboto Condensed
4 | - Font Author: Copyright 2011 Google Inc. All Rights Reserved.
5 | - Font Source: http://fonts.gstatic.com/s/robotocondensed/v25/ieVl2ZhZI2eCN5jzbjEETS9weq8-59WxDCs5cvI.ttf
6 | - Font License: Apache License, version 2.0 (http://www.apache.org/licenses/LICENSE-2.0.html))
7 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 | import { loadWASM } from 'onigasm';
6 |
7 | (async () => {
8 | await loadWASM('web/onigasm.wasm');
9 | ReactDOM.render(
10 |
11 |
12 | ,
13 | document.getElementById('root')
14 | );
15 | })();
16 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/src/components/Ad.js:
--------------------------------------------------------------------------------
1 | import React, { useEffect } from "react";
2 |
3 | export const Ad = () => {
4 | useEffect(() => {
5 | const script = document.createElement("script");
6 |
7 | script.src = "https://media.ethicalads.io/media/client/ethicalads.min.js";
8 | script.async = true;
9 |
10 | document.body.appendChild(script);
11 |
12 | return () => {
13 | document.body.removeChild(script);
14 | };
15 | }, []);
16 |
17 | return
;
18 | };
19 |
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/public/patterns/squid:
--------------------------------------------------------------------------------
1 | # Pattern squid3
2 | # Documentation of squid3 logs formats can be found at the following link:
3 | # http://wiki.squid-cache.org/Features/LogFormat
4 | SQUID3_STATUS (?:%{POSINT:[http][response][status_code]:int}|0|000)
5 | SQUID3 %{NUMBER:timestamp}\s+%{NUMBER:[squid][request][duration]:int}\s%{IP:[source][ip]}\s%{WORD:[event][action]}/%{SQUID3_STATUS}\s%{INT:[http][response][bytes]:int}\s%{WORD:[http][request][method]}\s%{NOTSPACE:[url][original]}\s(?:-|%{NOTSPACE:[user][name]})\s%{WORD:[squid][hierarchy_code]}/(?:-|%{IPORHOST:[destination][address]})\s(?:-|%{NOTSPACE:[http][response][mime_type]})
6 | # :long - %{INT:[http][response][bytes]:int}
7 |
--------------------------------------------------------------------------------
/public/patterns/mongodb:
--------------------------------------------------------------------------------
1 | MONGO_LOG %{SYSLOGTIMESTAMP:timestamp} \[%{WORD:[mongodb][component]}\] %{GREEDYDATA:message}
2 | MONGO_QUERY \{ (?<={ ).*(?= } ntoreturn:) \}
3 | MONGO_SLOWQUERY %{WORD:[mongodb][profile][op]} %{MONGO_WORDDASH:[mongodb][database]}\.%{MONGO_WORDDASH:[mongodb][collection]} %{WORD}: %{MONGO_QUERY:[mongodb][query][original]} ntoreturn:%{NONNEGINT:[mongodb][profile][ntoreturn]:int} ntoskip:%{NONNEGINT:[mongodb][profile][ntoskip]:int} nscanned:%{NONNEGINT:[mongodb][profile][nscanned]:int}.*? nreturned:%{NONNEGINT:[mongodb][profile][nreturned]:int}.*? %{INT:[mongodb][profile][duration]:int}ms
4 | MONGO_WORDDASH \b[\w-]+\b
5 | MONGO3_SEVERITY \w
6 | MONGO3_COMPONENT %{WORD}
7 | MONGO3_LOG %{TIMESTAMP_ISO8601:timestamp} %{MONGO3_SEVERITY:[log][level]} (?:-|%{MONGO3_COMPONENT:[mongodb][component]})%{SPACE}(?:\[%{DATA:[mongodb][context]}\])? %{GREEDYDATA:message}
8 |
--------------------------------------------------------------------------------
/public/patterns/bind:
--------------------------------------------------------------------------------
1 | BIND9_TIMESTAMP %{MONTHDAY}[-]%{MONTH}[-]%{YEAR} %{TIME}
2 |
3 | BIND9_DNSTYPE (?:A|AAAA|CAA|CDNSKEY|CDS|CERT|CNAME|CSYNC|DLV|DNAME|DNSKEY|DS|HINFO|LOC|MX|NAPTR|NS|NSEC|NSEC3|OPENPGPKEY|PTR|RRSIG|RP|SIG|SMIMEA|SOA|SRV|TSIG|TXT|URI)
4 | BIND9_CATEGORY (?:queries)
5 |
6 | # dns.question.class is static - only 'IN' is supported by Bind9
7 | # bind.log.question.name is expected to be a 'duplicate' (same as the dns.question.name capture)
8 | BIND9_QUERYLOGBASE client(:? @0x(?:[0-9A-Fa-f]+))? %{IP:[client][ip]}#%{POSINT:[client][port]:int} \(%{GREEDYDATA:[bind][log][question][name]}\): query: %{GREEDYDATA:[dns][question][name]} (?<[dns][question][class]>IN) %{BIND9_DNSTYPE:[dns][question][type]}(:? %{DATA:[bind][log][question][flags]})? \(%{IP:[server][ip]}\)
9 |
10 | # for query-logging category and severity are always fixed as "queries: info: "
11 | BIND9_QUERYLOG %{BIND9_TIMESTAMP:timestamp} %{BIND9_CATEGORY:[bind][log][category]}: %{LOGLEVEL:[log][level]}: %{BIND9_QUERYLOGBASE}
12 |
13 | BIND9 %{BIND9_QUERYLOG}
14 |
--------------------------------------------------------------------------------
/src/codemirror/grok.js:
--------------------------------------------------------------------------------
1 | export default {
2 | // The start state contains the rules that are intially used
3 | start: [
4 | // The regex matches the token, the token property contains the type
5 | // You can match multiple tokens at once. Note that the captured
6 | // groups must span the whole string in this case
7 | // { regex: /(%{)([^:]+)(:?)([^}]+)(})/, token: [null, 'keyword', null, 'string', null] },
8 | // Rules are matched in the order in which they ap
9 | { regex: /(%{)([^:}]+)(})/, token: ['def', 'operator', 'def'] },
10 | { regex: /(%{)([^:}]+)(:)([^}]+)(})/, token: ['def', 'operator', 'def', 'keyword', 'def'] },
11 | { regex: /(\\)([\[|\.|\^|\$|\*|\+|\?|\(|\)|\[|\{|\\|\||\]])/, token: ['qualifier', null] },
12 | { regex: /(\()(\?)(<)([^>]+)(>)/, token: [null, 'def', 'def', 'keyword', 'def'] },
13 | ],
14 | // The meta property contains global information about the mode. It
15 | // can contain properties like lineComment, which are supported by
16 | // all modes, and also directives like dontIndentStates, which are
17 | // specific to simple modes.
18 | meta: {},
19 | };
20 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Conor Slack
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/public/patterns/rails:
--------------------------------------------------------------------------------
1 | RUUID \h{32}
2 | # rails controller with action
3 | RCONTROLLER (?<[rails][controller][class]>[^#]+)#(?<[rails][controller][action]>\w+)
4 |
5 | # this will often be the only line:
6 | RAILS3HEAD (?m)Started %{WORD:[http][request][method]} "%{URIPATHPARAM:[url][original]}" for %{IPORHOST:[source][address]} at (?%{YEAR}-%{MONTHNUM}-%{MONTHDAY} %{HOUR}:%{MINUTE}:%{SECOND} %{ISO8601_TIMEZONE})
7 | # for some a strange reason, params are stripped of {} - not sure that's a good idea.
8 | RPROCESSING \W*Processing by %{RCONTROLLER} as (?<[rails][request][format]>\S+)(?:\W*Parameters: {%{DATA:[rails][request][params]}}\W*)?
9 | RAILS3FOOT Completed %{POSINT:[http][response][status_code]:int}%{DATA} in %{NUMBER:[rails][request][duration][total]:float}ms %{RAILS3PROFILE}%{GREEDYDATA}
10 | RAILS3PROFILE (?:\(Views: %{NUMBER:[rails][request][duration][view]:float}ms \| ActiveRecord: %{NUMBER:[rails][request][duration][active_record]:float}ms|\(ActiveRecord: %{NUMBER:[rails][request][duration][active_record]:float}ms)?
11 |
12 | # putting it all together
13 | RAILS3 %{RAILS3HEAD}(?:%{RPROCESSING})?(?<[rails][request][explain][original]>(?:%{DATA}\n)*)(?:%{RAILS3FOOT})?
14 |
--------------------------------------------------------------------------------
/public/patterns/linux-syslog:
--------------------------------------------------------------------------------
1 | SYSLOG5424PRINTASCII [!-~]+
2 |
3 | SYSLOGBASE2 (?:%{SYSLOGTIMESTAMP:timestamp}|%{TIMESTAMP_ISO8601:timestamp})(?: %{SYSLOGFACILITY})?(?: %{SYSLOGHOST:[host][hostname]})?(?: %{SYSLOGPROG}:)?
4 | SYSLOGPAMSESSION %{SYSLOGBASE} (?=%{GREEDYDATA:message})%{WORD:[system][auth][pam][module]}\(%{DATA:[system][auth][pam][origin]}\): session %{WORD:[system][auth][pam][session_state]} for user %{USERNAME:[user][name]}(?: by %{GREEDYDATA})?
5 |
6 | CRON_ACTION [A-Z ]+
7 | CRONLOG %{SYSLOGBASE} \(%{USER:[user][name]}\) %{CRON_ACTION:[system][cron][action]} \(%{DATA:message}\)
8 |
9 | SYSLOGLINE %{SYSLOGBASE2} %{GREEDYDATA:message}
10 |
11 | # IETF 5424 syslog(8) format (see http://www.rfc-editor.org/info/rfc5424)
12 | SYSLOG5424PRI <%{NONNEGINT:[log][syslog][priority]:int}>
13 | SYSLOG5424SD \[%{DATA}\]+
14 | SYSLOG5424BASE %{SYSLOG5424PRI}%{NONNEGINT:[system][syslog][version]} +(?:-|%{TIMESTAMP_ISO8601:timestamp}) +(?:-|%{IPORHOST:[host][hostname]}) +(?:-|%{SYSLOG5424PRINTASCII:[process][name]}) +(?:-|%{POSINT:[process][pid]:int}) +(?:-|%{SYSLOG5424PRINTASCII:[event][code]}) +(?:-|%{SYSLOG5424SD:[system][syslog][structured_data]})?
15 |
16 | SYSLOG5424LINE %{SYSLOG5424BASE} +%{GREEDYDATA:message}
17 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-app",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^4.2.4",
7 | "@testing-library/react": "^9.5.0",
8 | "@testing-library/user-event": "^7.2.1",
9 | "codemirror": "^5.57.0",
10 | "grok-js": "github:cjslack/grok-js-web",
11 | "node-fetch": "^2.6.1",
12 | "onigasm": "^2.2.5",
13 | "oniguruma": "^7.2.1",
14 | "react": "^16.13.1",
15 | "react-codemirror2": "^7.2.1",
16 | "react-dom": "^16.13.1",
17 | "react-feather": "^2.0.8",
18 | "react-scripts": "^3.4.4",
19 | "react-select": "^5.7.0",
20 | "simplebar-react": "^2.2.1"
21 | },
22 | "scripts": {
23 | "start": "react-scripts start",
24 | "build": "react-scripts build",
25 | "test": "react-scripts test",
26 | "eject": "react-scripts eject"
27 | },
28 | "eslintConfig": {
29 | "extends": "react-app"
30 | },
31 | "browserslist": {
32 | "production": [
33 | ">0.2%",
34 | "not dead",
35 | "not op_mini all"
36 | ],
37 | "development": [
38 | "last 1 chrome version",
39 | "last 1 firefox version",
40 | "last 1 safari version"
41 | ]
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/components/Navbar.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { GitHub } from "react-feather";
3 |
4 | const styles = {
5 | navbar: {
6 | display: "flex",
7 | justifyContent: "space-between",
8 | alignItems: "center",
9 | backgroundColor: "var(--dark)",
10 | padding: "0 1rem",
11 | height: "3.5rem",
12 | width: "100%",
13 | position: "fixed",
14 | boxShadow: "-2px 2px rgba(0, 0, 0, .2)",
15 | zIndex: 1,
16 | },
17 | navLinks: {
18 | display: "flex",
19 | justifyContent: "flex-end",
20 | alignItems: "center",
21 | },
22 | };
23 |
24 | export const Navbar = () => {
25 | return (
26 |
27 |
28 | {/* {'%{'} */}
29 | Grok
30 | {/* : */}
31 | Debugger
32 | {/* {'}'} */}
33 |
34 |
40 |
41 | );
42 | };
43 |
--------------------------------------------------------------------------------
/public/patterns/httpd:
--------------------------------------------------------------------------------
1 | HTTPDUSER %{EMAILADDRESS}|%{USER}
2 | HTTPDERROR_DATE %{DAY} %{MONTH} %{MONTHDAY} %{TIME} %{YEAR}
3 |
4 | # Log formats
5 | HTTPD_COMMONLOG %{IPORHOST:[source][address]} (?:-|%{HTTPDUSER:[apache][access][user][identity]}) (?:-|%{HTTPDUSER:[user][name]}) \[%{HTTPDATE:timestamp}\] "(?:%{WORD:[http][request][method]} %{NOTSPACE:[url][original]}(?: HTTP/%{NUMBER:[http][version]})?|%{DATA})" (?:-|%{INT:[http][response][status_code]:int}) (?:-|%{INT:[http][response][body][bytes]:int})
6 | # :long - %{INT:[http][response][body][bytes]:int}
7 | HTTPD_COMBINEDLOG %{HTTPD_COMMONLOG} "(?:-|%{DATA:[http][request][referrer]})" "(?:-|%{DATA:[user_agent][original]})"
8 |
9 | # Error logs
10 | HTTPD20_ERRORLOG \[%{HTTPDERROR_DATE:timestamp}\] \[%{LOGLEVEL:[log][level]}\] (?:\[client %{IPORHOST:[source][address]}\] )?%{GREEDYDATA:message}
11 | HTTPD24_ERRORLOG \[%{HTTPDERROR_DATE:timestamp}\] \[(?:%{WORD:[apache][error][module]})?:%{LOGLEVEL:[log][level]}\] \[pid %{POSINT:[process][pid]:int}(:tid %{INT:[process][thread][id]:int})?\](?: \(%{POSINT:[apache][error][proxy][error][code]?}\)%{DATA:[apache][error][proxy][error][message]}:)?(?: \[client %{IPORHOST:[source][address]}(?::%{POSINT:[source][port]:int})?\])?(?: %{DATA:[error][code]}:)? %{GREEDYDATA:message}
12 | # :long - %{INT:[process][thread][id]:int}
13 | HTTPD_ERRORLOG %{HTTPD20_ERRORLOG}|%{HTTPD24_ERRORLOG}
14 |
15 | # Deprecated
16 | COMMONAPACHELOG %{HTTPD_COMMONLOG}
17 | COMBINEDAPACHELOG %{HTTPD_COMBINEDLOG}
18 |
--------------------------------------------------------------------------------
/src/hooks/useLocalStorage.js:
--------------------------------------------------------------------------------
1 | import { useState } from "react";
2 |
3 | export default function useLocalStorage(key, initialValue) {
4 | // State to store our value
5 | // Pass initial state function to useState so logic is only executed once
6 | const [storedValue, setStoredValue] = useState(() => {
7 | if (typeof window === "undefined") {
8 | return initialValue;
9 | }
10 |
11 | try {
12 | // Get from local storage by key
13 | const item = window.localStorage.getItem(key);
14 | // Parse stored json or if none return initialValue
15 | return item ? JSON.parse(item) : initialValue;
16 | } catch (error) {
17 | // If error also return initialValue
18 | console.log(error);
19 | return initialValue;
20 | }
21 | });
22 |
23 | // Return a wrapped version of useState's setter function that ...
24 | // ... persists the new value to localStorage.
25 | const setValue = (value) => {
26 | try {
27 | // Allow value to be a function so we have same API as useState
28 | const valueToStore = value instanceof Function ? value(storedValue) : value;
29 | // Save state
30 | setStoredValue(valueToStore);
31 | // Save to local storage
32 | if (typeof window !== "undefined") {
33 | window.localStorage.setItem(key, JSON.stringify(valueToStore));
34 | }
35 | } catch (error) {
36 | // A more advanced implementation would handle the error case
37 | console.log(error);
38 | }
39 | };
40 |
41 | return [storedValue, setValue];
42 | }
43 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [grokdebugger.com](https://www.grokdebugger.com)
2 |
3 | This client-side application uses WebAssembly to emulate the logstash grok library in the browser. It is responsive, feature-rich, and can help you quickly debug your grok patterns. Although it works well in most cases, it is not an exact port of logstash grok, so be sure to test your patterns in your environment before deploying.
4 |
5 | **Features:**
6 |
7 | - Real-time processing (see changes as you type)
8 | - Autocomplete
9 | - Match highlighting
10 | - Syntax highlighting
11 | - Multiline debugging
12 | - 20+ pattern sets (AWS, Grok, firewalls, Java, etc.)
13 | - Add more pattern sets with a URL
14 | - Save and use your own custom patterns
15 |
16 | **Limitations:**
17 |
18 | - Does not support nested objects in naming e.g. `%{IP:user.ip}` or `<%{NONNEGINT:[log][syslog][priority]}>`
19 | - Does not support explicitly defined output types e.g. `%{NUMBER:status:int}`
20 | - Does not support inline flag modifiers e.g. `(?i)opid=%{NOTSPACE:event_operation_id}` https://github.com/cjslack/grok-debugger/issues/6
21 |
22 | **Run locally:**
23 |
24 | Must have [node.js](https://nodejs.org/en) installed
25 | ```
26 | git clone https://github.com/cjslack/grok-debugger.git
27 | cd grok-debugger
28 | npm install
29 | npm start
30 | ```
31 |
32 | **How I made this:**
33 |
34 | [node-grok](https://github.com/Beh01der/node-grok) is a library that emulates the grok libarary, but it is not an exact port of it. I [forked](https://github.com/cjslack/grok-js-web) this node.js library and adapted it to run in the browser with Web Assembly.
35 |
--------------------------------------------------------------------------------
/public/patterns/junos:
--------------------------------------------------------------------------------
1 | # JUNOS 11.4 RT_FLOW patterns
2 | RT_FLOW_TAG (?:RT_FLOW_SESSION_CREATE|RT_FLOW_SESSION_CLOSE|RT_FLOW_SESSION_DENY)
3 | # deprecated legacy name:
4 | RT_FLOW_EVENT RT_FLOW_TAG
5 |
6 | RT_FLOW1 %{RT_FLOW_TAG:[juniper][srx][tag]}: %{GREEDYDATA:[juniper][srx][reason]}: %{IP:[source][ip]}/%{INT:[source][port]:int}->%{IP:[destination][ip]}/%{INT:[destination][port]:int} %{DATA:[juniper][srx][service_name]} %{IP:[source][nat][ip]}/%{INT:[source][nat][port]:int}->%{IP:[destination][nat][ip]}/%{INT:[destination][nat][port]:int} (?:(?:None)|(?:%{DATA:[juniper][srx][src_nat_rule_name]})) (?:(?:None)|(?:%{DATA:[juniper][srx][dst_nat_rule_name]})) %{INT:[network][iana_number]} %{DATA:[rule][name]} %{DATA:[observer][ingress][zone]} %{DATA:[observer][egress][zone]} %{INT:[juniper][srx][session_id]} \d+\(%{INT:[source][bytes]:int}\) \d+\(%{INT:[destination][bytes]:int}\) %{INT:[juniper][srx][elapsed_time]:int} .*
7 | # :long - %{INT:[source][bytes]:int}
8 | # :long - %{INT:[destination][bytes]:int}
9 |
10 | RT_FLOW2 %{RT_FLOW_TAG:[juniper][srx][tag]}: session created %{IP:[source][ip]}/%{INT:[source][port]:int}->%{IP:[destination][ip]}/%{INT:[destination][port]:int} %{DATA:[juniper][srx][service_name]} %{IP:[source][nat][ip]}/%{INT:[source][nat][port]:int}->%{IP:[destination][nat][ip]}/%{INT:[destination][nat][port]:int} (?:(?:None)|(?:%{DATA:[juniper][srx][src_nat_rule_name]})) (?:(?:None)|(?:%{DATA:[juniper][srx][dst_nat_rule_name]})) %{INT:[network][iana_number]} %{DATA:[rule][name]} %{DATA:[observer][ingress][zone]} %{DATA:[observer][egress][zone]} %{INT:[juniper][srx][session_id]} .*
11 |
12 | RT_FLOW3 %{RT_FLOW_TAG:[juniper][srx][tag]}: session denied %{IP:[source][ip]}/%{INT:[source][port]:int}->%{IP:[destination][ip]}/%{INT:[destination][port]:int} %{DATA:[juniper][srx][service_name]} %{INT:[network][iana_number]}\(\d\) %{DATA:[rule][name]} %{DATA:[observer][ingress][zone]} %{DATA:[observer][egress][zone]} .*
13 |
14 |
--------------------------------------------------------------------------------
/public/patterns/exim:
--------------------------------------------------------------------------------
1 | EXIM_MSGID [0-9A-Za-z]{6}-[0-9A-Za-z]{6}-[0-9A-Za-z]{2}
2 | # <= message arrival
3 | # => normal message delivery
4 | # -> additional address in same delivery
5 | # *> delivery suppressed by -N
6 | # ** delivery failed; address bounced
7 | # == delivery deferred; temporary problem
8 | EXIM_FLAGS (?:<=|=>|->|\*>|\*\*|==|<>|>>)
9 | EXIM_DATE (:?%{YEAR}-%{MONTHNUM}-%{MONTHDAY} %{TIME})
10 | EXIM_PID \[%{POSINT:[process][pid]:int}\]
11 | EXIM_QT ((\d+y)?(\d+w)?(\d+d)?(\d+h)?(\d+m)?(\d+s)?)
12 | EXIM_EXCLUDE_TERMS (Message is frozen|(Start|End) queue run| Warning: | retry time not reached | no (IP address|host name) found for (IP address|host) | unexpected disconnection while reading SMTP command | no immediate delivery: |another process is handling this message)
13 | EXIM_REMOTE_HOST (H=(%{NOTSPACE:[source][address]} )?(\(%{NOTSPACE:[exim][log][remote_address]}\) )?\[%{IP:[source][ip]}\](?::%{POSINT:[source][port]:int})?)
14 | EXIM_INTERFACE (I=\[%{IP:[destination][ip]}\](?::%{NUMBER:[destination][port]:int}))
15 | EXIM_PROTOCOL (P=%{NOTSPACE:[network][protocol]})
16 | EXIM_MSG_SIZE (S=%{NUMBER:[exim][log][message][size]:int})
17 | EXIM_HEADER_ID (id=%{NOTSPACE:[exim][log][header_id]})
18 | EXIM_QUOTED_CONTENT (?:\\.|[^\\"])*
19 | EXIM_SUBJECT (T="%{EXIM_QUOTED_CONTENT:[exim][log][message][subject]}")
20 |
21 | EXIM_UNKNOWN_FIELD (?:[A-Za-z0-9]{1,4}=(?:%{QUOTEDSTRING}|%{NOTSPACE}))
22 | EXIM_NAMED_FIELDS (?: (?:%{EXIM_REMOTE_HOST}|%{EXIM_INTERFACE}|%{EXIM_PROTOCOL}|%{EXIM_MSG_SIZE}|%{EXIM_HEADER_ID}|%{EXIM_SUBJECT}|%{EXIM_UNKNOWN_FIELD}))*
23 |
24 | EXIM_MESSAGE_ARRIVAL %{EXIM_DATE:timestamp} (?:%{EXIM_PID} )?%{EXIM_MSGID:[exim][log][message][id]} (?<[exim][log][flags]><=) (?<[exim][log][status]>[a-z:] )?%{EMAILADDRESS:[exim][log][sender][email]}%{EXIM_NAMED_FIELDS}(?:(?: from %{DATA:[exim][log][sender][original]}>?)? for %{EMAILADDRESS:[exim][log][recipient][email]})?
25 |
26 | EXIM %{EXIM_MESSAGE_ARRIVAL}
27 |
--------------------------------------------------------------------------------
/src/components/LoadModal.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { X, Edit2, Trash2 } from "react-feather";
3 |
4 | export const LoadModal = ({ setShowModal, customPatterns, setCustomPatterns, setPattern }) => {
5 | const handleDelete = (id) => {
6 | const updatedCustomPatterns = customPatterns.filter((p) => p.id !== id);
7 | setCustomPatterns(updatedCustomPatterns);
8 | };
9 |
10 | const handleEdit = (id) => {
11 | const pattern = customPatterns.find((p) => p.id === id);
12 | setPattern(pattern.pattern);
13 | setShowModal(null);
14 | };
15 |
16 | return (
17 |
18 |
19 |
20 |
Edit Custom Patterns
21 | setShowModal(null)} />
22 |
23 |
24 | {!!customPatterns.length ? (
25 |
26 |
27 |
Name
28 |
Pattern
29 |
30 |
31 | {customPatterns.map((pattern) => {
32 | return (
33 |
34 |
{pattern.id}
35 |
{pattern.pattern}
36 |
handleEdit(pattern.id)}>
37 |
38 |
39 |
handleDelete(pattern.id)}>
40 |
41 |
42 |
43 | );
44 | })}
45 |
46 |
47 | ) : (
48 |
No custom patterns yet
49 | )}
50 |
51 |
52 |
53 | );
54 | };
55 |
--------------------------------------------------------------------------------
/src/components/ShareModal.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect, useRef } from "react";
2 | import { X, AlertTriangle, Copy } from "react-feather";
3 |
4 | export const ShareModal = ({ setShowModal, pattern, sample }) => {
5 | const [showWarn, setShowWarn] = useState(false);
6 | const [url, setUrl] = useState("");
7 |
8 | const [copyIndicator, setCopyIndicator] = useState(false);
9 |
10 | const ref = useRef();
11 |
12 | const onLoad = async () => {
13 | setUrl(
14 | window.location.origin + "?pattern=" + encodeURIComponent(pattern) + "&sample=" + encodeURIComponent(sample)
15 | // + "&collections=" +
16 | // encodeURIComponent(JSON.stringify(collections.filter((c) => c.active)))
17 | );
18 | };
19 |
20 | useEffect(() => {
21 | onLoad();
22 | }, []);
23 |
24 | useEffect(() => {
25 | ref.current.select();
26 | if (url.length > 2000) return setShowWarn(true);
27 | setShowWarn(false);
28 | }, [url]);
29 |
30 | const handleSubmit = (e) => {
31 | e.preventDefault();
32 | navigator.clipboard.writeText(url);
33 | setCopyIndicator(true);
34 | setTimeout(() => {
35 | setCopyIndicator(false);
36 | }, 2000);
37 | };
38 |
39 | return (
40 |
41 |
42 |
43 |
Share
44 | setShowModal(null)} />
45 |
46 |
63 |
64 |
65 | );
66 | };
67 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
13 |
14 |
18 |
19 |
28 | Grok Debugger | Autocomplete and Live Match Highlghting
29 |
30 |
31 |
32 |
33 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/public/patterns/java:
--------------------------------------------------------------------------------
1 | JAVACLASS (?:[a-zA-Z$_][a-zA-Z$_0-9]*\.)*[a-zA-Z$_][a-zA-Z$_0-9]*
2 | #Space is an allowed character to match special cases like 'Native Method' or 'Unknown Source'
3 | JAVAFILE (?:[a-zA-Z$_0-9. -]+)
4 | #Allow special , methods
5 | JAVAMETHOD (?:(<(?:cl)?init>)|[a-zA-Z$_][a-zA-Z$_0-9]*)
6 | #Line number is optional in special cases 'Native method' or 'Unknown source'
7 | JAVASTACKTRACEPART %{SPACE}at %{JAVACLASS:[java][log][origin][class][name]}\.%{JAVAMETHOD:[log][origin][function]}\(%{JAVAFILE:[log][origin][file][name]}(?::%{INT:[log][origin][file][line]:int})?\)
8 | # Java Logs
9 | JAVATHREAD (?:[A-Z]{2}-Processor[\d]+)
10 | JAVALOGMESSAGE (?:.*)
11 |
12 | # MMM dd, yyyy HH:mm:ss eg: Jan 9, 2014 7:13:13 AM
13 | # matches default logging configuration in Tomcat 4.1, 5.0, 5.5, 6.0, 7.0
14 | CATALINA7_DATESTAMP %{MONTH} %{MONTHDAY}, %{YEAR} %{HOUR}:%{MINUTE}:%{SECOND} (?:AM|PM)
15 | CATALINA7_LOG %{CATALINA7_DATESTAMP:timestamp} %{JAVACLASS:[java][log][origin][class][name]}(?: %{JAVAMETHOD:[log][origin][function]})?\s*(?:%{LOGLEVEL:[log][level]}:)? %{JAVALOGMESSAGE:message}
16 |
17 | # 31-Jul-2020 16:40:38.578 in Tomcat 8.5/9.0
18 | CATALINA8_DATESTAMP %{MONTHDAY}-%{MONTH}-%{YEAR} %{HOUR}:%{MINUTE}:%{SECOND}
19 | CATALINA8_LOG %{CATALINA8_DATESTAMP:timestamp} %{LOGLEVEL:[log][level]} \[%{DATA:[java][log][origin][thread][name]}\] %{JAVACLASS:[java][log][origin][class][name]}\.(?:%{JAVAMETHOD:[log][origin][function]})? %{JAVALOGMESSAGE:message}
20 |
21 | CATALINA_DATESTAMP (?:%{CATALINA8_DATESTAMP})|(?:%{CATALINA7_DATESTAMP})
22 | CATALINALOG (?:%{CATALINA8_LOG})|(?:%{CATALINA7_LOG})
23 |
24 | # in Tomcat 5.5, 6.0, 7.0 it is the same as catalina.out logging format
25 | TOMCAT7_LOG %{CATALINA7_LOG}
26 | TOMCAT8_LOG %{CATALINA8_LOG}
27 |
28 | # NOTE: a weird log we started with - not sure what TC version this should match out of the box (due the | delimiters)
29 | TOMCATLEGACY_DATESTAMP %{YEAR}-%{MONTHNUM}-%{MONTHDAY} %{HOUR}:%{MINUTE}:%{SECOND}(?: %{ISO8601_TIMEZONE})?
30 | TOMCATLEGACY_LOG %{TOMCATLEGACY_DATESTAMP:timestamp} \| %{LOGLEVEL:[log][level]} \| %{JAVACLASS:[java][log][origin][class][name]} - %{JAVALOGMESSAGE:message}
31 |
32 | TOMCAT_DATESTAMP (?:%{CATALINA8_DATESTAMP})|(?:%{CATALINA7_DATESTAMP})|(?:%{TOMCATLEGACY_DATESTAMP})
33 |
34 | TOMCATLOG (?:%{TOMCAT8_LOG})|(?:%{TOMCAT7_LOG})|(?:%{TOMCATLEGACY_LOG})
35 |
--------------------------------------------------------------------------------
/src/components/SaveModal.js:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from 'react';
2 | import { Save, X, XOctagon, AlertTriangle } from 'react-feather';
3 |
4 | export const SaveModal = ({ setShowModal, pattern, savedPatterns, setSavedPatterns }) => {
5 | const [title, setTitle] = useState('');
6 | const [showWarn, setShowWarn] = useState(false);
7 | const [showError, setShowError] = useState(false);
8 |
9 | const handleSubmit = async (e) => {
10 | e.preventDefault();
11 | if (!(title && pattern)) {
12 | return setShowError(true);
13 | }
14 | localStorage.setItem('grokdebugger-' + title, pattern);
15 | setSavedPatterns([...savedPatterns.filter((p) => p.title !== title), { title, pattern }]);
16 | setShowModal(null);
17 | };
18 |
19 | useEffect(() => {
20 | let timeout = setTimeout(() => {
21 | if (savedPatterns.find((p) => p.title === title)) {
22 | setShowWarn(true);
23 | } else {
24 | setShowWarn(false);
25 | }
26 | }, 250);
27 | return () => clearTimeout(timeout);
28 | }, [title]);
29 |
30 | return (
31 |
32 |
33 |
34 |
Save Pattern
35 | setShowModal(null)} />
36 |
37 |
60 |
61 |
62 | );
63 | };
64 |
--------------------------------------------------------------------------------
/src/components/CustomPatternModal.js:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useRef, useState } from "react";
2 | import { AlertTriangle, PlusSquare, Save, X } from "react-feather";
3 |
4 | const nameRegex = /^([A-Z0-9_]+)$/;
5 |
6 | export const CustomPatternModal = ({
7 | setShowModal,
8 | groks,
9 | pattern,
10 | setPattern,
11 | patterns,
12 | customPatterns,
13 | setCustomPatterns,
14 | }) => {
15 | const [name, setName] = useState("");
16 | const [warnMessage, setWarnMessage] = useState(null);
17 |
18 | const firstUpdate = useRef(true);
19 |
20 | useEffect(() => {
21 | if (pattern == "") {
22 | return setWarnMessage("Grok pattern cannot be blank.");
23 | }
24 | if (firstUpdate.current) {
25 | firstUpdate.current = false;
26 | return;
27 | }
28 | let timeout = setTimeout(() => {
29 | if (!nameRegex.test(name)) {
30 | return setWarnMessage("Pattern name can only contain letters, numbers, or underscores.");
31 | }
32 | if (patterns.map((p) => p.id).includes(name)) {
33 | return setWarnMessage("This pattern name already exists in a collection. Try another name.");
34 | } else {
35 | return setWarnMessage(null);
36 | }
37 | }, 500);
38 | return () => clearTimeout(timeout);
39 | }, [name]);
40 |
41 | const handleSubmit = (e) => {
42 | e.preventDefault();
43 | if (warnMessage) return;
44 | groks.createPattern(pattern, name);
45 | setCustomPatterns(() => [...customPatterns, { id: name, pattern }]);
46 | setPattern(() => `%{${name}}`);
47 | setShowModal(null);
48 | };
49 |
50 | return (
51 |
52 |
53 |
54 |
Add as Custom Pattern
55 | setShowModal(null)} />
56 |
57 |
84 |
85 |
86 | );
87 | };
88 |
--------------------------------------------------------------------------------
/public/patterns/haproxy:
--------------------------------------------------------------------------------
1 |
2 | HAPROXYTIME (?!<[0-9])%{HOUR}:%{MINUTE}(?::%{SECOND})(?![0-9])
3 | HAPROXYDATE %{MONTHDAY}/%{MONTH}/%{YEAR}:%{HAPROXYTIME}.%{INT}
4 |
5 | # Override these default patterns to parse out what is captured in your haproxy.cfg
6 | HAPROXYCAPTUREDREQUESTHEADERS %{DATA:[haproxy][http][request][captured_headers]}
7 | HAPROXYCAPTUREDRESPONSEHEADERS %{DATA:[haproxy][http][response][captured_headers]}
8 |
9 | # Example:
10 | # These haproxy config lines will add data to the logs that are captured
11 | # by the patterns below. Place them in your custom patterns directory to
12 | # override the defaults.
13 | #
14 | # capture request header Host len 40
15 | # capture request header X-Forwarded-For len 50
16 | # capture request header Accept-Language len 50
17 | # capture request header Referer len 200
18 | # capture request header User-Agent len 200
19 | #
20 | # capture response header Content-Type len 30
21 | # capture response header Content-Encoding len 10
22 | # capture response header Cache-Control len 200
23 | # capture response header Last-Modified len 200
24 | #
25 | # HAPROXYCAPTUREDREQUESTHEADERS %{DATA:[haproxy][http][request][host]}\|%{DATA:[haproxy][http][request][x_forwarded_for]}\|%{DATA:[haproxy][http][request][accept_language]}\|%{DATA:[http][request][referrer]}\|%{DATA:[user_agent][original]}
26 | # HAPROXYCAPTUREDRESPONSEHEADERS %{DATA:[http][response][mime_type]}\|%{DATA:[haproxy][http][response][encoding]}\|%{DATA:[haproxy][http][response][cache_control]}\|%{DATA:[haproxy][http][response][last_modified]}
27 |
28 | HAPROXYURI (?:%{URIPROTO:[url][scheme]}://)?(?:%{USER:[url][username]}(?::[^@]*)?@)?(?:%{IPORHOST:[url][domain]}(?::%{POSINT:[url][port]:int})?)?(?:%{URIPATH:[url][path]}(?:\?%{URIQUERY:[url][query]})?)?
29 |
30 | HAPROXYHTTPREQUESTLINE (?:|(?:%{WORD:[http][request][method]} %{HAPROXYURI:[url][original]}(?: HTTP/%{NUMBER:[http][version]})?))
31 |
32 | # parse a haproxy 'httplog' line
33 | HAPROXYHTTPBASE %{IP:[source][address]}:%{INT:[source][port]:int} \[%{HAPROXYDATE:[haproxy][request_date]}\] %{NOTSPACE:[haproxy][frontend_name]} %{NOTSPACE:[haproxy][backend_name]}/(?:|%{NOTSPACE:[haproxy][server_name]}) (?:-1|%{INT:[haproxy][http][request][time_wait_ms]:int})/(?:-1|%{INT:[haproxy][total_waiting_time_ms]:int})/(?:-1|%{INT:[haproxy][connection_wait_time_ms]:int})/(?:-1|%{INT:[haproxy][http][request][time_wait_without_data_ms]:int})/%{NOTSPACE:[haproxy][total_time_ms]} %{INT:[http][response][status_code]:int} %{INT:[source][bytes]:int} (?:-|%{DATA:[haproxy][http][request][captured_cookie]}) (?:-|%{DATA:[haproxy][http][response][captured_cookie]}) %{NOTSPACE:[haproxy][termination_state]} %{INT:[haproxy][connections][active]:int}/%{INT:[haproxy][connections][frontend]:int}/%{INT:[haproxy][connections][backend]:int}/%{INT:[haproxy][connections][server]:int}/%{INT:[haproxy][connections][retries]:int} %{INT:[haproxy][server_queue]:int}/%{INT:[haproxy][backend_queue]:int}(?: \{%{HAPROXYCAPTUREDREQUESTHEADERS}\}(?: \{%{HAPROXYCAPTUREDRESPONSEHEADERS}\})?)?(?: "%{HAPROXYHTTPREQUESTLINE}"?)?
34 | # :long - %{INT:[source][bytes]:int}
35 |
36 | HAPROXYHTTP (?:%{SYSLOGTIMESTAMP:timestamp}|%{TIMESTAMP_ISO8601:timestamp}) %{IPORHOST:[host][hostname]} %{SYSLOGPROG}: %{HAPROXYHTTPBASE}
37 |
38 | # parse a haproxy 'tcplog' line
39 | HAPROXYTCP (?:%{SYSLOGTIMESTAMP:timestamp}|%{TIMESTAMP_ISO8601:timestamp}) %{IPORHOST:[host][hostname]} %{SYSLOGPROG}: %{IP:[source][address]}:%{INT:[source][port]:int} \[%{HAPROXYDATE:[haproxy][request_date]}\] %{NOTSPACE:[haproxy][frontend_name]} %{NOTSPACE:[haproxy][backend_name]}/(?:|%{NOTSPACE:[haproxy][server_name]}) (?:-1|%{INT:[haproxy][total_waiting_time_ms]:int})/(?:-1|%{INT:[haproxy][connection_wait_time_ms]:int})/%{NOTSPACE:[haproxy][total_time_ms]} %{INT:[source][bytes]:int} %{NOTSPACE:[haproxy][termination_state]} %{INT:[haproxy][connections][active]:int}/%{INT:[haproxy][connections][frontend]:int}/%{INT:[haproxy][connections][backend]:int}/%{INT:[haproxy][connections][server]:int}/%{INT:[haproxy][connections][retries]:int} %{INT:[haproxy][server_queue]:int}/%{INT:[haproxy][backend_queue]:int}
40 | # :long - %{INT:[source][bytes]:int}
41 |
--------------------------------------------------------------------------------
/public/patterns/bro:
--------------------------------------------------------------------------------
1 | # supports the 'old' BRO log files, for updated Zeek log format see the patters/ecs-v1/zeek
2 | # https://www.bro.org/sphinx/script-reference/log-files.html
3 |
4 | BRO_BOOL [TF]
5 | BRO_DATA [^\t]+
6 |
7 | # http.log - old format (before the Zeek rename) :
8 | BRO_HTTP %{NUMBER:timestamp}\t%{NOTSPACE:[zeek][session_id]}\t%{IP:[source][ip]}\t%{INT:[source][port]:int}\t%{IP:[destination][ip]}\t%{INT:[destination][port]:int}\t%{INT:[zeek][http][trans_depth]:int}\t(?:-|%{WORD:[http][request][method]})\t(?:-|%{BRO_DATA:[url][domain]})\t(?:-|%{BRO_DATA:[url][original]})\t(?:-|%{BRO_DATA:[http][request][referrer]})\t(?:-|%{BRO_DATA:[user_agent][original]})\t(?:-|%{NUMBER:[http][request][body][bytes]:int})\t(?:-|%{NUMBER:[http][response][body][bytes]:int})\t(?:-|%{POSINT:[http][response][status_code]:int})\t(?:-|%{DATA:[zeek][http][status_msg]})\t(?:-|%{POSINT:[zeek][http][info_code]:int})\t(?:-|%{DATA:[zeek][http][info_msg]})\t(?:-|%{BRO_DATA:[zeek][http][filename]})\t(?:\(empty\)|%{BRO_DATA:[zeek][http][tags]})\t(?:-|%{BRO_DATA:[url][username]})\t(?:-|%{BRO_DATA:[url][password]})\t(?:-|%{BRO_DATA:[zeek][http][proxied]})\t(?:-|%{BRO_DATA:[zeek][http][orig_fuids]})\t(?:-|%{BRO_DATA:[http][request][mime_type]})\t(?:-|%{BRO_DATA:[zeek][http][resp_fuids]})\t(?:-|%{BRO_DATA:[http][response][mime_type]})
9 | # :long - %{NUMBER:[http][request][body][bytes]:int}
10 | # :long - %{NUMBER:[http][response][body][bytes]:int}
11 |
12 | # dns.log - old format
13 | BRO_DNS %{NUMBER:timestamp}\t%{NOTSPACE:[zeek][session_id]}\t%{IP:[source][ip]}\t%{INT:[source][port]:int}\t%{IP:[destination][ip]}\t%{INT:[destination][port]:int}\t%{WORD:[network][transport]}\t(?:-|%{INT:[dns][id]:int})\t(?:-|%{BRO_DATA:[dns][question][name]})\t(?:-|%{INT:[zeek][dns][qclass]:int})\t(?:-|%{BRO_DATA:[zeek][dns][qclass_name]})\t(?:-|%{INT:[zeek][dns][qtype]:int})\t(?:-|%{BRO_DATA:[dns][question][type]})\t(?:-|%{INT:[zeek][dns][rcode]:int})\t(?:-|%{BRO_DATA:[dns][response_code]})\t(?:-|%{BRO_BOOL:[zeek][dns][AA]})\t(?:-|%{BRO_BOOL:[zeek][dns][TC]})\t(?:-|%{BRO_BOOL:[zeek][dns][RD]})\t(?:-|%{BRO_BOOL:[zeek][dns][RA]})\t(?:-|%{NONNEGINT:[zeek][dns][Z]:int})\t(?:-|%{BRO_DATA:[zeek][dns][answers]})\t(?:-|%{DATA:[zeek][dns][TTLs]})\t(?:-|%{BRO_BOOL:[zeek][dns][rejected]})
14 |
15 | # conn.log - old bro, also supports 'newer' format (optional *zeek.connection.local_resp* flag) compared to non-ecs mode
16 | BRO_CONN %{NUMBER:timestamp}\t%{NOTSPACE:[zeek][session_id]}\t%{IP:[source][ip]}\t%{INT:[source][port]:int}\t%{IP:[destination][ip]}\t%{INT:[destination][port]:int}\t%{WORD:[network][transport]}\t(?:-|%{BRO_DATA:[network][protocol]})\t(?:-|%{NUMBER:[zeek][connection][duration]:float})\t(?:-|%{INT:[zeek][connection][orig_bytes]:int})\t(?:-|%{INT:[zeek][connection][resp_bytes]:int})\t(?:-|%{BRO_DATA:[zeek][connection][state]})\t(?:-|%{BRO_BOOL:[zeek][connection][local_orig]})\t(?:(?:-|%{BRO_BOOL:[zeek][connection][local_resp]})\t)?(?:-|%{INT:[zeek][connection][missed_bytes]:int})\t(?:-|%{BRO_DATA:[zeek][connection][history]})\t(?:-|%{INT:[source][packets]:int})\t(?:-|%{INT:[source][bytes]:int})\t(?:-|%{INT:[destination][packets]:int})\t(?:-|%{INT:[destination][bytes]:int})\t(?:\(empty\)|%{BRO_DATA:[zeek][connection][tunnel_parents]})
17 | # :long - %{INT:[zeek][connection][orig_bytes]:int}
18 | # :long - %{INT:[zeek][connection][resp_bytes]:int}
19 | # :long - %{INT:[zeek][connection][missed_bytes]:int}
20 | # :long - %{INT:[source][packets]:int}
21 | # :long - %{INT:[source][bytes]:int}
22 | # :long - %{INT:[destination][packets]:int}
23 | # :long - %{INT:[destination][bytes]:int}
24 |
25 | # files.log - old format
26 | BRO_FILES %{NUMBER:timestamp}\t%{NOTSPACE:[zeek][files][fuid]}\t(?:-|%{IP:[server][ip]})\t(?:-|%{IP:[client][ip]})\t(?:-|%{BRO_DATA:[zeek][files][session_ids]})\t(?:-|%{BRO_DATA:[zeek][files][source]})\t(?:-|%{INT:[zeek][files][depth]:int})\t(?:-|%{BRO_DATA:[zeek][files][analyzers]})\t(?:-|%{BRO_DATA:[file][mime_type]})\t(?:-|%{BRO_DATA:[file][name]})\t(?:-|%{NUMBER:[zeek][files][duration]:float})\t(?:-|%{BRO_DATA:[zeek][files][local_orig]})\t(?:-|%{BRO_BOOL:[zeek][files][is_orig]})\t(?:-|%{INT:[zeek][files][seen_bytes]:int})\t(?:-|%{INT:[file][size]:int})\t(?:-|%{INT:[zeek][files][missing_bytes]:int})\t(?:-|%{INT:[zeek][files][overflow_bytes]:int})\t(?:-|%{BRO_BOOL:[zeek][files][timedout]})\t(?:-|%{BRO_DATA:[zeek][files][parent_fuid]})\t(?:-|%{BRO_DATA:[file][hash][md5]})\t(?:-|%{BRO_DATA:[file][hash][sha1]})\t(?:-|%{BRO_DATA:[file][hash][sha256]})\t(?:-|%{BRO_DATA:[zeek][files][extracted]})
27 | # :long - %{INT:[zeek][files][seen_bytes]:int}
28 | # :long - %{INT:[file][size]:int}
29 | # :long - %{INT:[zeek][files][missing_bytes]:int}
30 | # :long - %{INT:[zeek][files][overflow_bytes]:int}
31 |
--------------------------------------------------------------------------------
/public/patterns/aws:
--------------------------------------------------------------------------------
1 | S3_REQUEST_LINE (?:%{WORD:[http][request][method]} %{NOTSPACE:[url][original]}(?: HTTP/%{NUMBER:[http][version]})?)
2 |
3 | S3_ACCESS_LOG %{WORD:[aws][s3access][bucket_owner]} %{NOTSPACE:[aws][s3access][bucket]} \[%{HTTPDATE:timestamp}\] (?:-|%{IP:[client][ip]}) (?:-|%{NOTSPACE:[client][user][id]}) %{NOTSPACE:[aws][s3access][request_id]} %{NOTSPACE:[aws][s3access][operation]} (?:-|%{NOTSPACE:[aws][s3access][key]}) (?:-|"%{S3_REQUEST_LINE:[aws][s3access][request_uri]}") (?:-|%{INT:[http][response][status_code]:int}) (?:-|%{NOTSPACE:[aws][s3access][error_code]}) (?:-|%{INT:[aws][s3access][bytes_sent]:int}) (?:-|%{INT:[aws][s3access][object_size]:int}) (?:-|%{INT:[aws][s3access][total_time]:int}) (?:-|%{INT:[aws][s3access][turn_around_time]:int}) "(?:-|%{DATA:[http][request][referrer]})" "(?:-|%{DATA:[user_agent][original]})" (?:-|%{NOTSPACE:[aws][s3access][version_id]})(?: (?:-|%{NOTSPACE:[aws][s3access][host_id]}) (?:-|%{NOTSPACE:[aws][s3access][signature_version]}) (?:-|%{NOTSPACE:[tls][cipher]}) (?:-|%{NOTSPACE:[aws][s3access][authentication_type]}) (?:-|%{NOTSPACE:[aws][s3access][host_header]}) (?:-|%{NOTSPACE:[aws][s3access][tls_version]}))?
4 | # :long - %{INT:[aws][s3access][bytes_sent]:int}
5 | # :long - %{INT:[aws][s3access][object_size]:int}
6 |
7 | ELB_URIHOST %{IPORHOST:[url][domain]}(?::%{POSINT:[url][port]:int})?
8 | ELB_URIPATHQUERY %{URIPATH:[url][path]}(?:\?%{URIQUERY:[url][query]})?
9 | # deprecated - old name:
10 | ELB_URIPATHPARAM %{ELB_URIPATHQUERY}
11 | ELB_URI %{URIPROTO:[url][scheme]}://(?:%{USER:[url][username]}(?::[^@]*)?@)?(?:%{ELB_URIHOST})?(?:%{ELB_URIPATHQUERY})?
12 |
13 | ELB_REQUEST_LINE (?:%{WORD:[http][request][method]} %{ELB_URI:[url][original]}(?: HTTP/%{NUMBER:[http][version]})?)
14 |
15 | # pattern supports 'regular' HTTP ELB format
16 | ELB_V1_HTTP_LOG %{TIMESTAMP_ISO8601:timestamp} %{NOTSPACE:[aws][elb][name]} %{IP:[source][ip]}:%{INT:[source][port]:int} (?:-|(?:%{IP:[aws][elb][backend][ip]}:%{INT:[aws][elb][backend][port]:int})) (?:-1|%{NUMBER:[aws][elb][request_processing_time][sec]:float}) (?:-1|%{NUMBER:[aws][elb][backend_processing_time][sec]:float}) (?:-1|%{NUMBER:[aws][elb][response_processing_time][sec]:float}) %{INT:[http][response][status_code]:int} (?:-|%{INT:[aws][elb][backend][http][response][status_code]:int}) %{INT:[http][request][body][bytes]:int} %{INT:[http][response][body][bytes]:int} "%{ELB_REQUEST_LINE}"(?: "(?:-|%{DATA:[user_agent][original]})" (?:-|%{NOTSPACE:[tls][cipher]}) (?:-|%{NOTSPACE:[aws][elb][ssl_protocol]}))?
17 | # :long - %{INT:[http][request][body][bytes]:int}
18 | # :long - %{INT:[http][response][body][bytes]:int}
19 |
20 | ELB_ACCESS_LOG %{ELB_V1_HTTP_LOG}
21 |
22 | # Each edge location is identified by a three-letter code and an arbitrarily assigned number.
23 | # The three-letter IATA code typically represents an airport near the edge location.
24 | # examples: "LHR62-C2", "SFO5-P1", ""IND6", "CPT50"
25 | CLOUDFRONT_EDGE_LOCATION [A-Z]{3}[0-9]{1,2}(?:-[A-Z0-9]{2})?
26 |
27 | # pattern used to match a shorted format, that's why we have the optional part (starting with *http.version*) at the end
28 | CLOUDFRONT_ACCESS_LOG (?%{YEAR}-%{MONTHNUM}-%{MONTHDAY}\t%{TIME})\t%{CLOUDFRONT_EDGE_LOCATION:[aws][cloudfront][x_edge_location]}\t(?:-|%{INT:[destination][bytes]:int})\t%{IPORHOST:[source][ip]}\t%{WORD:[http][request][method]}\t%{HOSTNAME:[url][domain]}\t%{NOTSPACE:[url][path]}\t(?:(?:000)|%{INT:[http][response][status_code]:int})\t(?:-|%{DATA:[http][request][referrer]})\t%{DATA:[user_agent][original]}\t(?:-|%{DATA:[url][query]})\t(?:-|%{DATA:[aws][cloudfront][http][request][cookie]})\t%{WORD:[aws][cloudfront][x_edge_result_type]}\t%{NOTSPACE:[aws][cloudfront][x_edge_request_id]}\t%{HOSTNAME:[aws][cloudfront][http][request][host]}\t%{URIPROTO:[network][protocol]}\t(?:-|%{INT:[source][bytes]:int})\t%{NUMBER:[aws][cloudfront][time_taken]:float}\t(?:-|%{IP:[network][forwarded_ip]})\t(?:-|%{DATA:[aws][cloudfront][ssl_protocol]})\t(?:-|%{NOTSPACE:[tls][cipher]})\t%{WORD:[aws][cloudfront][x_edge_response_result_type]}(?:\t(?:-|HTTP/%{NUMBER:[http][version]})\t(?:-|%{DATA:[aws][cloudfront][fle_status]})\t(?:-|%{DATA:[aws][cloudfront][fle_encrypted_fields]})\t%{INT:[source][port]:int}\t%{NUMBER:[aws][cloudfront][time_to_first_byte]:float}\t(?:-|%{DATA:[aws][cloudfront][x_edge_detailed_result_type]})\t(?:-|%{NOTSPACE:[http][request][mime_type]})\t(?:-|%{INT:[aws][cloudfront][http][request][size]:int})\t(?:-|%{INT:[aws][cloudfront][http][request][range][start]:int})\t(?:-|%{INT:[aws][cloudfront][http][request][range][end]:int}))?
29 | # :long - %{INT:[destination][bytes]:int}
30 | # :long - %{INT:[source][bytes]:int}
31 | # :long - %{INT:[aws][cloudfront][http][request][size]:int}
32 | # :long - %{INT:[aws][cloudfront][http][request][range][start]:int}
33 | # :long - %{INT:[aws][cloudfront][http][request][range][end]:int}
34 |
--------------------------------------------------------------------------------
/src/components/MorePatternsModal.js:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | import { DownloadCloud, Trash2, X, XOctagon } from "react-feather";
3 |
4 | export const MorePatternsModal = ({ setShowModal, collections, setCollections, patterns, setPatterns, groks }) => {
5 | const urlRegex =
6 | /(https?:\/\/)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/;
7 | const titleRegex = /^[\w\d _-]{1,20}/;
8 |
9 | const [url, setUrl] = useState("");
10 | const [title, setTitle] = useState("");
11 | const [errorMessage, setErrorMessage] = useState("");
12 |
13 | const handleSubmit = async (e) => {
14 | // Validation
15 | e.preventDefault();
16 | setErrorMessage("");
17 | if (!urlRegex.test(url)) return setErrorMessage("URL is not valid");
18 | if (!titleRegex.test(title))
19 | return setErrorMessage("Title can only contain letters, numbers, spaces, underscores, and dashes.");
20 | if (collections.map((c) => c.label).includes(title))
21 | return setErrorMessage("This title is already assigned to a set. Choose another.");
22 | const random = (Math.random() + 1).toString(36).substring(7);
23 |
24 | // Attempt to load pattern
25 | try {
26 | const newPatterns = await groks.load(url).then((ids) => {
27 | return ids.map((id) => {
28 | return { id, collection: random };
29 | });
30 | });
31 | if (!newPatterns.length)
32 | return setErrorMessage("Error loading pattern set. Make sure the url and format of set is correct.");
33 | setPatterns((patterns) => [...patterns, ...newPatterns.flat()]);
34 | const updatedCollection = [...collections, { value: random, label: title, url, active: true }].sort(
35 | (a, b) => a.value > b.value
36 | );
37 | setCollections(updatedCollection);
38 | } catch (err) {
39 | console.log(err);
40 | setErrorMessage("Error loading pattern set");
41 | }
42 | };
43 |
44 | const handleDelete = (value) => {
45 | setCollections(collections.filter((c) => c.value !== value));
46 | setPatterns(patterns.filter((p) => p.collection !== value));
47 | };
48 |
49 | return (
50 |
51 |
52 |
53 |
Download Pattern Set from URL
54 | setShowModal(null)} />
55 |
56 |
120 |
121 |
122 | );
123 | };
124 |
--------------------------------------------------------------------------------
/public/patterns/zeek:
--------------------------------------------------------------------------------
1 | # updated Zeek log matching, for legacy matching see the patters/ecs-v1/bro
2 |
3 | ZEEK_BOOL [TF]
4 | ZEEK_DATA [^\t]+
5 |
6 | # http.log - the 'new' format (compared to BRO_HTTP)
7 | # has *version* and *origin* fields added and *filename* replaced with *orig_filenames* + *resp_filenames*
8 | ZEEK_HTTP %{NUMBER:timestamp}\t%{NOTSPACE:[zeek][session_id]}\t%{IP:[source][ip]}\t%{INT:[source][port]:int}\t%{IP:[destination][ip]}\t%{INT:[destination][port]:int}\t%{INT:[zeek][http][trans_depth]:int}\t(?:-|%{WORD:[http][request][method]})\t(?:-|%{ZEEK_DATA:[url][domain]})\t(?:-|%{ZEEK_DATA:[url][original]})\t(?:-|%{ZEEK_DATA:[http][request][referrer]})\t(?:-|%{NUMBER:[http][version]})\t(?:-|%{ZEEK_DATA:[user_agent][original]})\t(?:-|%{ZEEK_DATA:[zeek][http][origin]})\t(?:-|%{NUMBER:[http][request][body][bytes]:int})\t(?:-|%{NUMBER:[http][response][body][bytes]:int})\t(?:-|%{POSINT:[http][response][status_code]:int})\t(?:-|%{DATA:[zeek][http][status_msg]})\t(?:-|%{POSINT:[zeek][http][info_code]:int})\t(?:-|%{DATA:[zeek][http][info_msg]})\t(?:\(empty\)|%{ZEEK_DATA:[zeek][http][tags]})\t(?:-|%{ZEEK_DATA:[url][username]})\t(?:-|%{ZEEK_DATA:[url][password]})\t(?:-|%{ZEEK_DATA:[zeek][http][proxied]})\t(?:-|%{ZEEK_DATA:[zeek][http][orig_fuids]})\t(?:-|%{ZEEK_DATA:[zeek][http][orig_filenames]})\t(?:-|%{ZEEK_DATA:[http][request][mime_type]})\t(?:-|%{ZEEK_DATA:[zeek][http][resp_fuids]})\t(?:-|%{ZEEK_DATA:[zeek][http][resp_filenames]})\t(?:-|%{ZEEK_DATA:[http][response][mime_type]})
9 | # :long - %{NUMBER:[http][request][body][bytes]:int}
10 | # :long - %{NUMBER:[http][response][body][bytes]:int}
11 |
12 | # dns.log - 'updated' BRO_DNS format (added *zeek.dns.rtt*)
13 | ZEEK_DNS %{NUMBER:timestamp}\t%{NOTSPACE:[zeek][session_id]}\t%{IP:[source][ip]}\t%{INT:[source][port]:int}\t%{IP:[destination][ip]}\t%{INT:[destination][port]:int}\t%{WORD:[network][transport]}\t(?:-|%{INT:[dns][id]:int})\t(?:-|%{NUMBER:[zeek][dns][rtt]:float})\t(?:-|%{ZEEK_DATA:[dns][question][name]})\t(?:-|%{INT:[zeek][dns][qclass]:int})\t(?:-|%{ZEEK_DATA:[zeek][dns][qclass_name]})\t(?:-|%{INT:[zeek][dns][qtype]:int})\t(?:-|%{ZEEK_DATA:[dns][question][type]})\t(?:-|%{INT:[zeek][dns][rcode]:int})\t(?:-|%{ZEEK_DATA:[dns][response_code]})\t%{ZEEK_BOOL:[zeek][dns][AA]}\t%{ZEEK_BOOL:[zeek][dns][TC]}\t%{ZEEK_BOOL:[zeek][dns][RD]}\t%{ZEEK_BOOL:[zeek][dns][RA]}\t%{NONNEGINT:[zeek][dns][Z]:int}\t(?:-|%{ZEEK_DATA:[zeek][dns][answers]})\t(?:-|%{DATA:[zeek][dns][TTLs]})\t(?:-|%{ZEEK_BOOL:[zeek][dns][rejected]})
14 |
15 | # conn.log - the 'new' format (requires *zeek.connection.local_resp*, handles `(empty)` as `-` for tunnel_parents, and optional mac adresses)
16 | ZEEK_CONN %{NUMBER:timestamp}\t%{NOTSPACE:[zeek][session_id]}\t%{IP:[source][ip]}\t%{INT:[source][port]:int}\t%{IP:[destination][ip]}\t%{INT:[destination][port]:int}\t%{WORD:[network][transport]}\t(?:-|%{ZEEK_DATA:[network][protocol]})\t(?:-|%{NUMBER:[zeek][connection][duration]:float})\t(?:-|%{INT:[zeek][connection][orig_bytes]:int})\t(?:-|%{INT:[zeek][connection][resp_bytes]:int})\t(?:-|%{ZEEK_DATA:[zeek][connection][state]})\t(?:-|%{ZEEK_BOOL:[zeek][connection][local_orig]})\t(?:-|%{ZEEK_BOOL:[zeek][connection][local_resp]})\t(?:-|%{INT:[zeek][connection][missed_bytes]:int})\t(?:-|%{ZEEK_DATA:[zeek][connection][history]})\t(?:-|%{INT:[source][packets]:int})\t(?:-|%{INT:[source][bytes]:int})\t(?:-|%{INT:[destination][packets]:int})\t(?:-|%{INT:[destination][bytes]:int})\t(?:-|%{ZEEK_DATA:[zeek][connection][tunnel_parents]})(?:\t(?:-|%{COMMONMAC:[source][mac]})\t(?:-|%{COMMONMAC:[destination][mac]}))?
17 | # :long - %{INT:[zeek][connection][orig_bytes]:int}
18 | # :long - %{INT:[zeek][connection][resp_bytes]:int}
19 | # :long - %{INT:[zeek][connection][missed_bytes]:int}
20 | # :long - %{INT:[source][packets]:int}
21 | # :long - %{INT:[source][bytes]:int}
22 | # :long - %{INT:[destination][packets]:int}
23 | # :long - %{INT:[destination][bytes]:int}
24 |
25 | # files.log - updated BRO_FILES format (2 new fields added at the end)
26 | ZEEK_FILES_TX_HOSTS (?:-|%{IP:[server][ip]})|(?<[zeek][files][tx_hosts]>%{IP:[server][ip]}(?:[\s,]%{IP})+)
27 | ZEEK_FILES_RX_HOSTS (?:-|%{IP:[client][ip]})|(?<[zeek][files][rx_hosts]>%{IP:[client][ip]}(?:[\s,]%{IP})+)
28 | ZEEK_FILES %{NUMBER:timestamp}\t%{NOTSPACE:[zeek][files][fuid]}\t%{ZEEK_FILES_TX_HOSTS}\t%{ZEEK_FILES_RX_HOSTS}\t(?:-|%{ZEEK_DATA:[zeek][files][session_ids]})\t(?:-|%{ZEEK_DATA:[zeek][files][source]})\t(?:-|%{INT:[zeek][files][depth]:int})\t(?:-|%{ZEEK_DATA:[zeek][files][analyzers]})\t(?:-|%{ZEEK_DATA:[file][mime_type]})\t(?:-|%{ZEEK_DATA:[file][name]})\t(?:-|%{NUMBER:[zeek][files][duration]:float})\t(?:-|%{ZEEK_DATA:[zeek][files][local_orig]})\t(?:-|%{ZEEK_BOOL:[zeek][files][is_orig]})\t(?:-|%{INT:[zeek][files][seen_bytes]:int})\t(?:-|%{INT:[file][size]:int})\t(?:-|%{INT:[zeek][files][missing_bytes]:int})\t(?:-|%{INT:[zeek][files][overflow_bytes]:int})\t(?:-|%{ZEEK_BOOL:[zeek][files][timedout]})\t(?:-|%{ZEEK_DATA:[zeek][files][parent_fuid]})\t(?:-|%{ZEEK_DATA:[file][hash][md5]})\t(?:-|%{ZEEK_DATA:[file][hash][sha1]})\t(?:-|%{ZEEK_DATA:[file][hash][sha256]})\t(?:-|%{ZEEK_DATA:[zeek][files][extracted]})(?:\t(?:-|%{ZEEK_BOOL:[zeek][files][extracted_cutoff]})\t(?:-|%{INT:[zeek][files][extracted_size]:int}))?
29 | # :long - %{INT:[zeek][files][seen_bytes]:int}
30 | # :long - %{INT:[file][size]:int}
31 | # :long - %{INT:[zeek][files][missing_bytes]:int}
32 | # :long - %{INT:[zeek][files][overflow_bytes]:int}
33 | # :long - %{INT:[zeek][files][extracted_size]:int}
34 |
--------------------------------------------------------------------------------
/public/patterns/grok-patterns:
--------------------------------------------------------------------------------
1 | USERNAME [a-zA-Z0-9._-]+
2 | USER %{USERNAME}
3 | EMAILLOCALPART [a-zA-Z0-9!#$%&'*+\-/=?^_`{|}~]{1,64}(?:\.[a-zA-Z0-9!#$%&'*+\-/=?^_`{|}~]{1,62}){0,63}
4 | EMAILADDRESS %{EMAILLOCALPART}@%{HOSTNAME}
5 | INT (?:[+-]?(?:[0-9]+))
6 | BASE10NUM (?[+-]?(?:(?:[0-9]+(?:\.[0-9]+)?)|(?:\.[0-9]+)))
7 | NUMBER (?:%{BASE10NUM})
8 | BASE16NUM (?(?"(?>\\.|[^\\"]+)+"|""|(?>'(?>\\.|[^\\']+)+')|''|(?>`(?>\\.|[^\\`]+)+`)|``))
19 | UUID [A-Fa-f0-9]{8}-(?:[A-Fa-f0-9]{4}-){3}[A-Fa-f0-9]{12}
20 | # URN, allowing use of RFC 2141 section 2.3 reserved characters
21 | URN urn:[0-9A-Za-z][0-9A-Za-z-]{0,31}:(?:%[0-9a-fA-F]{2}|[0-9A-Za-z()+,.:=@;$_!*'/?#-])+
22 |
23 | # Networking
24 | MAC (?:%{CISCOMAC}|%{WINDOWSMAC}|%{COMMONMAC})
25 | CISCOMAC (?:(?:[A-Fa-f0-9]{4}\.){2}[A-Fa-f0-9]{4})
26 | WINDOWSMAC (?:(?:[A-Fa-f0-9]{2}-){5}[A-Fa-f0-9]{2})
27 | COMMONMAC (?:(?:[A-Fa-f0-9]{2}:){5}[A-Fa-f0-9]{2})
28 | IPV6 ((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?
29 | IPV4 (?[A-Za-z]+:|\\)(?:\\[^\\?*]*)+
40 | URIPROTO [A-Za-z]([A-Za-z0-9+\-.]+)+
41 | URIHOST %{IPORHOST}(?::%{POSINT})?
42 | # uripath comes loosely from RFC1738, but mostly from what Firefox doesn't turn into %XX
43 | URIPATH (?:/[A-Za-z0-9$.+!*'(){},~:;=@#%&_\-]*)+
44 | URIQUERY [A-Za-z0-9$.+!*'|(){},~@#%&/=:;_?\-\[\]<>]*
45 | # deprecated (kept due compatibility):
46 | URIPARAM \?%{URIQUERY}
47 | URIPATHPARAM %{URIPATH}(?:\?%{URIQUERY})?
48 | URI %{URIPROTO}://(?:%{USER}(?::[^@]*)?@)?(?:%{URIHOST})?(?:%{URIPATH}(?:\?%{URIQUERY})?)?
49 |
50 | # Months: January, Feb, 3, 03, 12, December
51 | MONTH \b(?:[Jj]an(?:uary|uar)?|[Ff]eb(?:ruary|ruar)?|[Mm](?:a|ä)?r(?:ch|z)?|[Aa]pr(?:il)?|[Mm]a(?:y|i)?|[Jj]un(?:e|i)?|[Jj]ul(?:y|i)?|[Aa]ug(?:ust)?|[Ss]ep(?:tember)?|[Oo](?:c|k)?t(?:ober)?|[Nn]ov(?:ember)?|[Dd]e(?:c|z)(?:ember)?)\b
52 | MONTHNUM (?:0?[1-9]|1[0-2])
53 | MONTHNUM2 (?:0[1-9]|1[0-2])
54 | MONTHDAY (?:(?:0[1-9])|(?:[12][0-9])|(?:3[01])|[1-9])
55 |
56 | # Days: Monday, Tue, Thu, etc...
57 | DAY (?:Mon(?:day)?|Tue(?:sday)?|Wed(?:nesday)?|Thu(?:rsday)?|Fri(?:day)?|Sat(?:urday)?|Sun(?:day)?)
58 |
59 | # Years?
60 | YEAR (?>\d\d){1,2}
61 | HOUR (?:2[0123]|[01]?[0-9])
62 | MINUTE (?:[0-5][0-9])
63 | # '60' is a leap second in most time standards and thus is valid.
64 | SECOND (?:(?:[0-5]?[0-9]|60)(?:[:.,][0-9]+)?)
65 | TIME (?!<[0-9])%{HOUR}:%{MINUTE}(?::%{SECOND})(?![0-9])
66 | # datestamp is YYYY/MM/DD-HH:MM:SS.UUUU (or something like it)
67 | DATE_US %{MONTHNUM}[/-]%{MONTHDAY}[/-]%{YEAR}
68 | DATE_EU %{MONTHDAY}[./-]%{MONTHNUM}[./-]%{YEAR}
69 | ISO8601_TIMEZONE (?:Z|[+-]%{HOUR}(?::?%{MINUTE}))
70 | ISO8601_SECOND %{SECOND}
71 | TIMESTAMP_ISO8601 %{YEAR}-%{MONTHNUM}-%{MONTHDAY}[T ]%{HOUR}:?%{MINUTE}(?::?%{SECOND})?%{ISO8601_TIMEZONE}?
72 | DATE %{DATE_US}|%{DATE_EU}
73 | DATESTAMP %{DATE}[- ]%{TIME}
74 | TZ (?:[APMCE][SD]T|UTC)
75 | DATESTAMP_RFC822 %{DAY} %{MONTH} %{MONTHDAY} %{YEAR} %{TIME} %{TZ}
76 | DATESTAMP_RFC2822 %{DAY}, %{MONTHDAY} %{MONTH} %{YEAR} %{TIME} %{ISO8601_TIMEZONE}
77 | DATESTAMP_OTHER %{DAY} %{MONTH} %{MONTHDAY} %{TIME} %{TZ} %{YEAR}
78 | DATESTAMP_EVENTLOG %{YEAR}%{MONTHNUM2}%{MONTHDAY}%{HOUR}%{MINUTE}%{SECOND}
79 |
80 | # Syslog Dates: Month Day HH:MM:SS
81 | SYSLOGTIMESTAMP %{MONTH} +%{MONTHDAY} %{TIME}
82 | PROG [\x21-\x5a\x5c\x5e-\x7e]+
83 | SYSLOGPROG %{PROG:[process][name]}(?:\[%{POSINT:[process][pid]:int}\])?
84 | SYSLOGHOST %{IPORHOST}
85 | SYSLOGFACILITY <%{NONNEGINT:[log][syslog][facility][code]:int}.%{NONNEGINT:[log][syslog][priority]:int}>
86 | HTTPDATE %{MONTHDAY}/%{MONTH}/%{YEAR}:%{TIME} %{INT}
87 |
88 | # Shortcuts
89 | QS %{QUOTEDSTRING}
90 |
91 | # Log formats
92 | SYSLOGBASE %{SYSLOGTIMESTAMP:timestamp} (?:%{SYSLOGFACILITY} )?%{SYSLOGHOST:[host][hostname]} %{SYSLOGPROG}:
93 |
94 | # Log Levels
95 | LOGLEVEL ([Aa]lert|ALERT|[Tt]race|TRACE|[Dd]ebug|DEBUG|[Nn]otice|NOTICE|[Ii]nfo?(?:rmation)?|INFO?(?:RMATION)?|[Ww]arn?(?:ing)?|WARN?(?:ING)?|[Ee]rr?(?:or)?|ERR?(?:OR)?|[Cc]rit?(?:ical)?|CRIT?(?:ICAL)?|[Ff]atal|FATAL|[Ss]evere|SEVERE|EMERG(?:ENCY)?|[Ee]merg(?:ency)?)
96 |
--------------------------------------------------------------------------------
/public/patterns/bacula:
--------------------------------------------------------------------------------
1 | BACULA_TIMESTAMP %{MONTHDAY}-%{MONTH}(?:-%{YEAR})? %{HOUR}:%{MINUTE}
2 | BACULA_HOST %{HOSTNAME}
3 | BACULA_VOLUME %{USER}
4 | BACULA_DEVICE %{USER}
5 | BACULA_DEVICEPATH %{UNIXPATH}
6 | BACULA_CAPACITY %{INT}{1,3}(,%{INT}{3})*
7 | BACULA_VERSION %{USER}
8 | BACULA_JOB %{USER}
9 |
10 | BACULA_LOG_MAX_CAPACITY User defined maximum volume capacity %{BACULA_CAPACITY:[bacula][volume][max_capacity]} exceeded on device \"%{BACULA_DEVICE:[bacula][volume][device]}\" \(%{BACULA_DEVICEPATH:[bacula][volume][path]}\).?
11 | BACULA_LOG_END_VOLUME End of medium on Volume \"%{BACULA_VOLUME:[bacula][volume][name]}\" Bytes=%{BACULA_CAPACITY:[bacula][volume][bytes]} Blocks=%{BACULA_CAPACITY:[bacula][volume][blocks]} at %{BACULA_TIMESTAMP:[bacula][timestamp]}.
12 | BACULA_LOG_NEW_VOLUME Created new Volume \"%{BACULA_VOLUME:[bacula][volume][name]}\" in catalog.
13 | BACULA_LOG_NEW_LABEL Labeled new Volume \"%{BACULA_VOLUME:[bacula][volume][name]}\" on (?:file )?device \"%{BACULA_DEVICE:[bacula][volume][device]}\" \(%{BACULA_DEVICEPATH:[bacula][volume][path]}\).
14 | BACULA_LOG_WROTE_LABEL Wrote label to prelabeled Volume \"%{BACULA_VOLUME:[bacula][volume][name]}\" on device \"%{BACULA_DEVICE:[bacula][volume][device]}\" \(%{BACULA_DEVICEPATH:[bacula][volume][path]}\)
15 | BACULA_LOG_NEW_MOUNT New volume \"%{BACULA_VOLUME:[bacula][volume][name]}\" mounted on device \"%{BACULA_DEVICE:[bacula][volume][device]}\" \(%{BACULA_DEVICEPATH:[bacula][volume][path]}\) at %{BACULA_TIMESTAMP:[bacula][timestamp]}.
16 | BACULA_LOG_NOOPEN \s*Cannot open %{DATA}: ERR=%{GREEDYDATA:[error][message]}
17 | BACULA_LOG_NOOPENDIR \s*Could not open directory \"?%{DATA:[file][path]}\"?: ERR=%{GREEDYDATA:[error][message]}
18 | BACULA_LOG_NOSTAT \s*Could not stat %{DATA:[file][path]}: ERR=%{GREEDYDATA:[error][message]}
19 | BACULA_LOG_NOJOBS There are no more Jobs associated with Volume \"%{BACULA_VOLUME:[bacula][volume][name]}\". Marking it purged.
20 | BACULA_LOG_ALL_RECORDS_PRUNED .*?All records pruned from Volume \"%{BACULA_VOLUME:[bacula][volume][name]}\"; marking it \"Purged\"
21 | BACULA_LOG_BEGIN_PRUNE_JOBS Begin pruning Jobs older than %{INT} month %{INT} days .
22 | BACULA_LOG_BEGIN_PRUNE_FILES Begin pruning Files.
23 | BACULA_LOG_PRUNED_JOBS Pruned %{INT} Jobs* for client %{BACULA_HOST:[bacula][client][name]} from catalog.
24 | BACULA_LOG_PRUNED_FILES Pruned Files from %{INT} Jobs* for client %{BACULA_HOST:[bacula][client][name]} from catalog.
25 | BACULA_LOG_ENDPRUNE End auto prune.
26 | BACULA_LOG_STARTJOB Start Backup JobId %{INT}, Job=%{BACULA_JOB:[bacula][job][name]}
27 | BACULA_LOG_STARTRESTORE Start Restore Job %{BACULA_JOB:[bacula][job][name]}
28 | BACULA_LOG_USEDEVICE Using Device \"%{BACULA_DEVICE:[bacula][volume][device]}\"
29 | BACULA_LOG_DIFF_FS \s*%{UNIXPATH} is a different filesystem. Will not descend from %{UNIXPATH} into it.
30 | BACULA_LOG_JOBEND Job write elapsed time = %{DATA:[bacula][job][elapsed_time]}, Transfer rate = %{NUMBER} (K|M|G)? Bytes/second
31 | BACULA_LOG_NOPRUNE_JOBS No Jobs found to prune.
32 | BACULA_LOG_NOPRUNE_FILES No Files found to prune.
33 | BACULA_LOG_VOLUME_PREVWRITTEN Volume \"?%{BACULA_VOLUME:[bacula][volume][name]}\"? previously written, moving to end of data.
34 | BACULA_LOG_READYAPPEND Ready to append to end of Volume \"%{BACULA_VOLUME:[bacula][volume][name]}\" size=%{INT:[bacula][volume][size]:int}
35 | # :long - %{INT:[bacula][volume][size]:int}
36 | BACULA_LOG_CANCELLING Cancelling duplicate JobId=%{INT:[bacula][job][other_id]}.
37 | BACULA_LOG_MARKCANCEL JobId %{INT:[bacula][job][id]}, Job %{BACULA_JOB:[bacula][job][name]} marked to be canceled.
38 | BACULA_LOG_CLIENT_RBJ shell command: run ClientRunBeforeJob \"%{GREEDYDATA:[bacula][job][client_run_before_command]}\"
39 | BACULA_LOG_VSS (Generate )?VSS (Writer)?
40 | BACULA_LOG_MAXSTART Fatal [eE]rror: Job canceled because max start delay time exceeded.
41 | BACULA_LOG_DUPLICATE Fatal [eE]rror: JobId %{INT:[bacula][job][other_id]} already running. Duplicate job not allowed.
42 | BACULA_LOG_NOJOBSTAT Fatal [eE]rror: No Job status returned from FD.
43 | BACULA_LOG_FATAL_CONN Fatal [eE]rror: bsock.c:133 Unable to connect to (Client: %{BACULA_HOST:[bacula][client][name]}|Storage daemon) on %{IPORHOST:[client][address]}:%{POSINT:[client][port]:int}. ERR=%{GREEDYDATA:[error][message]}
44 | BACULA_LOG_NO_CONNECT Warning: bsock.c:127 Could not connect to (Client: %{BACULA_HOST:[bacula][client][name]}|Storage daemon) on %{IPORHOST:[client][address]}:%{POSINT:[client][port]:int}. ERR=%{GREEDYDATA:[error][message]}
45 | BACULA_LOG_NO_AUTH Fatal error: Unable to authenticate with File daemon at \"?%{IPORHOST:[client][address]}(?::%{POSINT:[client][port]:int})?\"?. Possible causes:
46 | BACULA_LOG_NOSUIT No prior or suitable Full backup found in catalog. Doing FULL backup.
47 | BACULA_LOG_NOPRIOR No prior Full backup Job record found.
48 |
49 | BACULA_LOG_JOB (Error: )?Bacula %{BACULA_HOST} %{BACULA_VERSION} \(%{BACULA_VERSION}\):
50 |
51 | BACULA_LOG %{BACULA_TIMESTAMP:timestamp} %{BACULA_HOST:[host][hostname]}(?: JobId %{INT:[bacula][job][id]})?:? (%{BACULA_LOG_MAX_CAPACITY}|%{BACULA_LOG_END_VOLUME}|%{BACULA_LOG_NEW_VOLUME}|%{BACULA_LOG_NEW_LABEL}|%{BACULA_LOG_WROTE_LABEL}|%{BACULA_LOG_NEW_MOUNT}|%{BACULA_LOG_NOOPEN}|%{BACULA_LOG_NOOPENDIR}|%{BACULA_LOG_NOSTAT}|%{BACULA_LOG_NOJOBS}|%{BACULA_LOG_ALL_RECORDS_PRUNED}|%{BACULA_LOG_BEGIN_PRUNE_JOBS}|%{BACULA_LOG_BEGIN_PRUNE_FILES}|%{BACULA_LOG_PRUNED_JOBS}|%{BACULA_LOG_PRUNED_FILES}|%{BACULA_LOG_ENDPRUNE}|%{BACULA_LOG_STARTJOB}|%{BACULA_LOG_STARTRESTORE}|%{BACULA_LOG_USEDEVICE}|%{BACULA_LOG_DIFF_FS}|%{BACULA_LOG_JOBEND}|%{BACULA_LOG_NOPRUNE_JOBS}|%{BACULA_LOG_NOPRUNE_FILES}|%{BACULA_LOG_VOLUME_PREVWRITTEN}|%{BACULA_LOG_READYAPPEND}|%{BACULA_LOG_CANCELLING}|%{BACULA_LOG_MARKCANCEL}|%{BACULA_LOG_CLIENT_RBJ}|%{BACULA_LOG_VSS}|%{BACULA_LOG_MAXSTART}|%{BACULA_LOG_DUPLICATE}|%{BACULA_LOG_NOJOBSTAT}|%{BACULA_LOG_FATAL_CONN}|%{BACULA_LOG_NO_CONNECT}|%{BACULA_LOG_NO_AUTH}|%{BACULA_LOG_NOSUIT}|%{BACULA_LOG_JOB}|%{BACULA_LOG_NOPRIOR})
52 | # old (deprecated) name :
53 | BACULA_LOGLINE %{BACULA_LOG}
54 |
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | @import url("https://fonts.googleapis.com/css2?family=Work+Sans&display=swap");
2 | @import "./codemirror/codemirror.css";
3 | @import "../node_modules/codemirror/theme/material-darker.css";
4 | @import "../node_modules/codemirror/addon/scroll/simplescrollbars.css";
5 |
6 | :root {
7 | font-family: "Work Sans", sans-serif;
8 | color: #fff;
9 | --dark: #333;
10 | --light: #f0f0f0;
11 | }
12 |
13 | a {
14 | text-decoration: none;
15 | color: var(--light);
16 | }
17 |
18 | * {
19 | box-sizing: border-box;
20 | }
21 |
22 | body {
23 | padding: 0;
24 | margin: 0;
25 | background-color: #111;
26 | }
27 |
28 | h1,
29 | h2,
30 | h3,
31 | h4,
32 | h5 {
33 | margin: 0.5rem;
34 | padding: 0rem;
35 | display: block;
36 | }
37 |
38 | h3 {
39 | margin-right: 0;
40 | }
41 |
42 | td,
43 | th {
44 | height: 1rem;
45 | }
46 |
47 | ul {
48 | padding: 0 0.5rem;
49 | }
50 |
51 | li {
52 | list-style-type: none;
53 | }
54 |
55 | button {
56 | border: none;
57 | width: 100%;
58 | }
59 |
60 | input:disabled {
61 | border-color: rgba(0, 0, 0, 0.5);
62 | }
63 |
64 | .nav-links {
65 | display: flex;
66 | justify-content: flex-end;
67 | align-items: center;
68 | }
69 |
70 | .nav-links a {
71 | color: silver;
72 | margin: 0 0.5rem;
73 | padding: 0.25rem;
74 | display: flex;
75 | align-items: center;
76 | }
77 |
78 | .nav-links a:hover {
79 | color: var(--light);
80 | border-color: var(--light) !important;
81 | }
82 |
83 | .nav-links a span {
84 | margin: 0 0.25rem;
85 | }
86 |
87 | .container {
88 | display: grid;
89 | padding: 3rem 0 0 0;
90 | height: 100vh;
91 | grid-template-columns: 250px minmax(0, 4fr) minmax(0, 2fr);
92 | grid-template-areas: "menu main result";
93 | }
94 |
95 | .menu {
96 | grid-area: "menu";
97 | background-color: #222;
98 | padding: 0.5rem;
99 | box-shadow: 2px -2px rgba(0, 0, 0, 0.4);
100 | display: flex;
101 | flex-direction: column;
102 | justify-content: space-between;
103 | }
104 |
105 | .result {
106 | grid-area: "result";
107 | overflow: hidden;
108 | padding: 0.5rem 0.25rem 1rem 0.25rem;
109 | }
110 |
111 | .main {
112 | grid-area: "main";
113 | height: 100%;
114 | display: flex;
115 | flex-direction: column;
116 | position: relative;
117 | overflow: hidden;
118 | padding: 0.5rem 0.25rem 1rem 0.25rem;
119 | }
120 |
121 | .samples-wrapper {
122 | display: flex;
123 | flex-direction: column;
124 | position: relative;
125 | height: 100%;
126 | width: 100%;
127 | padding: 0.5rem 0.5rem 0 0.5rem;
128 | overflow: hidden;
129 | }
130 |
131 | .samples-wrapper > * {
132 | position: relative;
133 | overflow: hidden;
134 | }
135 |
136 | .output-top {
137 | display: flex;
138 | flex-direction: row;
139 | justify-content: space-between;
140 | align-items: center;
141 | padding-right: 0.5rem;
142 | }
143 |
144 | .counter {
145 | justify-self: flex-end;
146 | font-size: 1.2rem;
147 | display: flex;
148 | align-items: center;
149 | justify-content: center;
150 | }
151 |
152 | .counter.all-match {
153 | color: #93eea8;
154 | }
155 |
156 | .counter.no-match {
157 | color: #f78c6c;
158 | }
159 |
160 | /* MODAL */
161 |
162 | .modal {
163 | background-color: rgba(255, 255, 255, 0.3);
164 | position: fixed;
165 | z-index: 3;
166 | display: flex;
167 | align-items: flex-start;
168 | justify-content: center;
169 | width: 100%;
170 | height: 100%;
171 | padding-top: 5vh;
172 | top: 0;
173 | left: 0;
174 | }
175 |
176 | .modal-container {
177 | background-color: #222;
178 | padding: 1rem;
179 | border: 1px solid siver;
180 | box-shadow: 3px 3px rgba(0, 0, 0, 0.6);
181 | display: flex;
182 | flex-direction: column;
183 | border-radius: 5px;
184 | width: 50vw;
185 | }
186 |
187 | .modal-header {
188 | margin-top: 0;
189 | margin-bottom: 1rem;
190 | padding-bottom: 0.5rem;
191 | border-bottom: 1px solid #444;
192 | display: flex;
193 | justify-content: space-between;
194 | align-items: flex-start;
195 | }
196 |
197 | .modal-header h3 {
198 | margin: 0 0 0 0.5rem;
199 | }
200 |
201 | .modal-header svg {
202 | color: silver;
203 | }
204 |
205 | .modal-header svg:hover {
206 | color: #fff;
207 | cursor: pointer;
208 | }
209 |
210 | .grid-body {
211 | max-height: 75vh;
212 | overflow-y: auto;
213 | }
214 |
215 | .modal-content input {
216 | border-radius: 5px;
217 | font-size: 1rem;
218 | padding: 0.5rem;
219 | width: 100%;
220 | }
221 |
222 | .modal-footer {
223 | margin-top: 1rem;
224 | }
225 |
226 | .notification {
227 | display: flex;
228 | align-items: center;
229 | background-color: salmon;
230 | box-shadow: 2px 2px rgba(0, 0, 0, 0.6);
231 | width: 100%;
232 | padding: 0.5rem;
233 | border-radius: 5px;
234 | margin-bottom: 1rem;
235 | }
236 |
237 | .notification span {
238 | margin-left: 0.5rem;
239 | }
240 |
241 | .error {
242 | background-color: salmon;
243 | color: #000;
244 | }
245 |
246 | .warn {
247 | background-color: palegoldenrod;
248 | color: #000;
249 | }
250 |
251 | .row div {
252 | display: block;
253 | text-overflow: ellipsis;
254 | white-space: nowrap;
255 | overflow: hidden;
256 | width: 100%;
257 | padding-top: 0.5rem;
258 | margin: 0 0.5rem;
259 | }
260 |
261 | .grid-headers div {
262 | display: flex;
263 | align-items: center;
264 | }
265 |
266 | .pattern-grid {
267 | background-color: #333;
268 | }
269 |
270 | .pattern-grid .grid-headers {
271 | font-weight: bold;
272 | color: #fff;
273 | background-color: #555;
274 | display: grid;
275 | grid-template-columns: 2fr 6fr 3rem 3rem;
276 | padding: 0.5rem;
277 | border: 1px solid #444;
278 | height: 3rem;
279 | width: 100%;
280 | }
281 |
282 | .pattern-grid .row {
283 | display: grid;
284 | padding: 0.5rem;
285 | grid-template-columns: 2fr 6fr 3rem 3rem;
286 | border: 1px solid #666;
287 | border-top: none;
288 | }
289 |
290 | .btn.delete {
291 | background-color: salmon;
292 | width: 2rem;
293 | height: 2rem;
294 | }
295 |
296 | .btn.edit {
297 | background-color: #89ddff;
298 | width: 2rem;
299 | height: 2rem;
300 | }
301 |
302 | .btn.success {
303 | background-color: #93eea8;
304 | }
305 |
306 | .btn.secondary {
307 | background-color: transparent;
308 | color: var(--light);
309 | border: 1px solid silver;
310 | }
311 |
312 | .btn.secondary:active {
313 | background-color: transparent;
314 | color: #89ddff;
315 | border: 1px solid #89ddff;
316 | }
317 |
318 | .btn > span {
319 | font-size: 1rem;
320 | }
321 |
322 | /* DONT TOUCH */
323 |
324 | .pattern-wrapper {
325 | height: auto;
326 | display: flex;
327 | flex-direction: column;
328 | padding: 0.5rem 0.5rem 0rem 0.5rem;
329 | position: relative;
330 | }
331 |
332 | .input-menu {
333 | display: flex;
334 | align-items: center;
335 | }
336 |
337 | .input-menu svg {
338 | color: silver;
339 | margin-left: 1rem;
340 | }
341 |
342 | .input-menu svg:hover {
343 | color: #fff;
344 | cursor: pointer;
345 | }
346 |
347 | .input-menu svg:active {
348 | color: #89ddff;
349 | cursor: pointer;
350 | }
351 |
352 | .output-wrapper {
353 | padding: 0.5rem 0.5rem 0 0.5rem;
354 | height: 100%;
355 | display: flex;
356 | flex-direction: column;
357 | position: relative;
358 | overflow: hidden;
359 | }
360 |
361 | .output-wrapper > * {
362 | position: relative;
363 | overflow: hidden;
364 | }
365 |
366 | .collections-wrapper {
367 | padding: 1rem 0.5rem;
368 | }
369 |
370 | .collections-wrapper div a:hover {
371 | color: var(--light) !important;
372 | }
373 |
374 | .set-item {
375 | display: flex;
376 | align-items: center;
377 | justify-content: space-between;
378 | margin: 0rem 0.5rem;
379 | padding: 0.5rem;
380 | background-color: #333;
381 | border: 1px solid #666;
382 | }
383 |
384 | .react-codemirror2 {
385 | max-width: 100%;
386 | height: 100%;
387 | }
388 |
389 | .CodeMirror {
390 | border: 1px solid #666;
391 | }
392 |
393 | .CodeMirror-focused {
394 | border: 1px solid silver;
395 | }
396 |
397 | .btn {
398 | background-color: #89ddff;
399 | opacity: 0.9;
400 | padding: 0.5rem;
401 | border-radius: 5px;
402 | position: relative;
403 | color: var(--dark);
404 | display: flex;
405 | align-items: center;
406 | justify-content: center;
407 | box-shadow: 2px 2px rgba(0, 0, 0, 0.6);
408 | }
409 |
410 | button.btn :nth-child(1) {
411 | margin-right: 0.5rem;
412 | }
413 |
414 | .btn:hover {
415 | opacity: 1;
416 | cursor: pointer;
417 | }
418 |
419 | /* MULTI SELECT */
420 |
421 | /* MEDIA QUERIES */
422 |
423 | @media (max-width: 700px) {
424 | .navbar h1 {
425 | font-size: 1.5rem;
426 | }
427 | .navbar span.beta {
428 | display: none;
429 | }
430 | .nav-links span {
431 | display: none;
432 | }
433 | .nav-links svg {
434 | height: 1.2rem;
435 | width: 1.2rem;
436 | }
437 | .main {
438 | padding-bottom: 0;
439 | }
440 | .menu {
441 | display: none;
442 | }
443 | .container {
444 | grid-template-columns: auto;
445 | grid-template-rows: 1fr 1fr;
446 | grid-template-areas: "main" "result";
447 | }
448 | }
449 |
--------------------------------------------------------------------------------
/public/patterns/nagios:
--------------------------------------------------------------------------------
1 | ##################################################################################
2 | ##################################################################################
3 | # Chop Nagios log files to smithereens!
4 | #
5 | # A set of GROK filters to process logfiles generated by Nagios.
6 | # While it does not, this set intends to cover all possible Nagios logs.
7 | #
8 | # Some more work needs to be done to cover all External Commands:
9 | # http://old.nagios.org/developerinfo/externalcommands/commandlist.php
10 | #
11 | # If you need some support on these rules please contact:
12 | # Jelle Smet http://smetj.net
13 | #
14 | #################################################################################
15 | #################################################################################
16 |
17 | NAGIOSTIME \[%{NUMBER:timestamp}\]
18 |
19 | ###############################################
20 | ######## Begin nagios log types
21 | ###############################################
22 | NAGIOS_TYPE_CURRENT_SERVICE_STATE CURRENT SERVICE STATE
23 | NAGIOS_TYPE_CURRENT_HOST_STATE CURRENT HOST STATE
24 |
25 | NAGIOS_TYPE_SERVICE_NOTIFICATION SERVICE NOTIFICATION
26 | NAGIOS_TYPE_HOST_NOTIFICATION HOST NOTIFICATION
27 |
28 | NAGIOS_TYPE_SERVICE_ALERT SERVICE ALERT
29 | NAGIOS_TYPE_HOST_ALERT HOST ALERT
30 |
31 | NAGIOS_TYPE_SERVICE_FLAPPING_ALERT SERVICE FLAPPING ALERT
32 | NAGIOS_TYPE_HOST_FLAPPING_ALERT HOST FLAPPING ALERT
33 |
34 | NAGIOS_TYPE_SERVICE_DOWNTIME_ALERT SERVICE DOWNTIME ALERT
35 | NAGIOS_TYPE_HOST_DOWNTIME_ALERT HOST DOWNTIME ALERT
36 |
37 | NAGIOS_TYPE_PASSIVE_SERVICE_CHECK PASSIVE SERVICE CHECK
38 | NAGIOS_TYPE_PASSIVE_HOST_CHECK PASSIVE HOST CHECK
39 |
40 | NAGIOS_TYPE_SERVICE_EVENT_HANDLER SERVICE EVENT HANDLER
41 | NAGIOS_TYPE_HOST_EVENT_HANDLER HOST EVENT HANDLER
42 |
43 | NAGIOS_TYPE_EXTERNAL_COMMAND EXTERNAL COMMAND
44 | NAGIOS_TYPE_TIMEPERIOD_TRANSITION TIMEPERIOD TRANSITION
45 | ###############################################
46 | ######## End nagios log types
47 | ###############################################
48 |
49 | ###############################################
50 | ######## Begin external check types
51 | ###############################################
52 | NAGIOS_EC_DISABLE_SVC_CHECK DISABLE_SVC_CHECK
53 | NAGIOS_EC_ENABLE_SVC_CHECK ENABLE_SVC_CHECK
54 | NAGIOS_EC_DISABLE_HOST_CHECK DISABLE_HOST_CHECK
55 | NAGIOS_EC_ENABLE_HOST_CHECK ENABLE_HOST_CHECK
56 | NAGIOS_EC_PROCESS_SERVICE_CHECK_RESULT PROCESS_SERVICE_CHECK_RESULT
57 | NAGIOS_EC_PROCESS_HOST_CHECK_RESULT PROCESS_HOST_CHECK_RESULT
58 | NAGIOS_EC_SCHEDULE_SERVICE_DOWNTIME SCHEDULE_SERVICE_DOWNTIME
59 | NAGIOS_EC_SCHEDULE_HOST_DOWNTIME SCHEDULE_HOST_DOWNTIME
60 | NAGIOS_EC_DISABLE_HOST_SVC_NOTIFICATIONS DISABLE_HOST_SVC_NOTIFICATIONS
61 | NAGIOS_EC_ENABLE_HOST_SVC_NOTIFICATIONS ENABLE_HOST_SVC_NOTIFICATIONS
62 | NAGIOS_EC_DISABLE_HOST_NOTIFICATIONS DISABLE_HOST_NOTIFICATIONS
63 | NAGIOS_EC_ENABLE_HOST_NOTIFICATIONS ENABLE_HOST_NOTIFICATIONS
64 | NAGIOS_EC_DISABLE_SVC_NOTIFICATIONS DISABLE_SVC_NOTIFICATIONS
65 | NAGIOS_EC_ENABLE_SVC_NOTIFICATIONS ENABLE_SVC_NOTIFICATIONS
66 | ###############################################
67 | ######## End external check types
68 | ###############################################
69 | NAGIOS_WARNING Warning:%{SPACE}%{GREEDYDATA:message}
70 |
71 | NAGIOS_CURRENT_SERVICE_STATE %{NAGIOS_TYPE_CURRENT_SERVICE_STATE:[nagios][log][type]}: %{DATA:[host][hostname]};%{DATA:[service][name]};%{DATA:[service][state]};%{DATA:[nagios][log][state_type]};%{INT:[nagios][log][attempt]:int};%{GREEDYDATA:message}
72 | NAGIOS_CURRENT_HOST_STATE %{NAGIOS_TYPE_CURRENT_HOST_STATE:[nagios][log][type]}: %{DATA:[host][hostname]};%{DATA:[service][state]};%{DATA:[nagios][log][state_type]};%{INT:[nagios][log][attempt]:int};%{GREEDYDATA:message}
73 |
74 | NAGIOS_SERVICE_NOTIFICATION %{NAGIOS_TYPE_SERVICE_NOTIFICATION:[nagios][log][type]}: %{DATA:[user][name]};%{DATA:[host][hostname]};%{DATA:[service][name]};%{DATA:[service][state]};%{DATA:[nagios][log][notification_command]};%{GREEDYDATA:message}
75 | NAGIOS_HOST_NOTIFICATION %{NAGIOS_TYPE_HOST_NOTIFICATION:[nagios][log][type]}: %{DATA:[user][name]};%{DATA:[host][hostname]};%{DATA:[service][state]};%{DATA:[nagios][log][notification_command]};%{GREEDYDATA:message}
76 |
77 | NAGIOS_SERVICE_ALERT %{NAGIOS_TYPE_SERVICE_ALERT:[nagios][log][type]}: %{DATA:[host][hostname]};%{DATA:[service][name]};%{DATA:[service][state]};%{DATA:[nagios][log][state_type]};%{INT:[nagios][log][attempt]:int};%{GREEDYDATA:message}
78 | NAGIOS_HOST_ALERT %{NAGIOS_TYPE_HOST_ALERT:[nagios][log][type]}: %{DATA:[host][hostname]};%{DATA:[service][state]};%{DATA:[nagios][log][state_type]};%{INT:[nagios][log][attempt]:int};%{GREEDYDATA:message}
79 |
80 | NAGIOS_SERVICE_FLAPPING_ALERT %{NAGIOS_TYPE_SERVICE_FLAPPING_ALERT:[nagios][log][type]}: %{DATA:[host][hostname]};%{DATA:[service][name]};%{DATA:[service][state]};%{GREEDYDATA:message}
81 | NAGIOS_HOST_FLAPPING_ALERT %{NAGIOS_TYPE_HOST_FLAPPING_ALERT:[nagios][log][type]}: %{DATA:[host][hostname]};%{DATA:[service][state]};%{GREEDYDATA:message}
82 |
83 | NAGIOS_SERVICE_DOWNTIME_ALERT %{NAGIOS_TYPE_SERVICE_DOWNTIME_ALERT:[nagios][log][type]}: %{DATA:[host][hostname]};%{DATA:[service][name]};%{DATA:[service][state]};%{GREEDYDATA:[nagios][log][comment]}
84 | NAGIOS_HOST_DOWNTIME_ALERT %{NAGIOS_TYPE_HOST_DOWNTIME_ALERT:[nagios][log][type]}: %{DATA:[host][hostname]};%{DATA:[service][state]};%{GREEDYDATA:[nagios][log][comment]}
85 |
86 | NAGIOS_PASSIVE_SERVICE_CHECK %{NAGIOS_TYPE_PASSIVE_SERVICE_CHECK:[nagios][log][type]}: %{DATA:[host][hostname]};%{DATA:[service][name]};%{DATA:[service][state]};%{GREEDYDATA:[nagios][log][comment]}
87 | NAGIOS_PASSIVE_HOST_CHECK %{NAGIOS_TYPE_PASSIVE_HOST_CHECK:[nagios][log][type]}: %{DATA:[host][hostname]};%{DATA:[service][state]};%{GREEDYDATA:[nagios][log][comment]}
88 |
89 | NAGIOS_SERVICE_EVENT_HANDLER %{NAGIOS_TYPE_SERVICE_EVENT_HANDLER:[nagios][log][type]}: %{DATA:[host][hostname]};%{DATA:[service][name]};%{DATA:[service][state]};%{DATA:[nagios][log][state_type]};%{DATA:[nagios][log][event_handler_name]}
90 | NAGIOS_HOST_EVENT_HANDLER %{NAGIOS_TYPE_HOST_EVENT_HANDLER:[nagios][log][type]}: %{DATA:[host][hostname]};%{DATA:[service][state]};%{DATA:[nagios][log][state_type]};%{DATA:[nagios][log][event_handler_name]}
91 |
92 | NAGIOS_TIMEPERIOD_TRANSITION %{NAGIOS_TYPE_TIMEPERIOD_TRANSITION:[nagios][log][type]}: %{DATA:[service][name]};%{NUMBER:[nagios][log][period_from]:int};%{NUMBER:[nagios][log][period_to]:int}
93 |
94 | ####################
95 | #### External checks
96 | ####################
97 |
98 | #Disable host & service check
99 | NAGIOS_EC_LINE_DISABLE_SVC_CHECK %{NAGIOS_TYPE_EXTERNAL_COMMAND:[nagios][log][type]}: %{NAGIOS_EC_DISABLE_SVC_CHECK:[nagios][log][command]};%{DATA:[host][hostname]};%{DATA:[service][name]}
100 | NAGIOS_EC_LINE_DISABLE_HOST_CHECK %{NAGIOS_TYPE_EXTERNAL_COMMAND:[nagios][log][type]}: %{NAGIOS_EC_DISABLE_HOST_CHECK:[nagios][log][command]};%{DATA:[host][hostname]}
101 |
102 | #Enable host & service check
103 | NAGIOS_EC_LINE_ENABLE_SVC_CHECK %{NAGIOS_TYPE_EXTERNAL_COMMAND:[nagios][log][type]}: %{NAGIOS_EC_ENABLE_SVC_CHECK:[nagios][log][command]};%{DATA:[host][hostname]};%{DATA:[service][name]}
104 | NAGIOS_EC_LINE_ENABLE_HOST_CHECK %{NAGIOS_TYPE_EXTERNAL_COMMAND:[nagios][log][type]}: %{NAGIOS_EC_ENABLE_HOST_CHECK:[nagios][log][command]};%{DATA:[host][hostname]}
105 |
106 | #Process host & service check
107 | NAGIOS_EC_LINE_PROCESS_SERVICE_CHECK_RESULT %{NAGIOS_TYPE_EXTERNAL_COMMAND:[nagios][log][type]}: %{NAGIOS_EC_PROCESS_SERVICE_CHECK_RESULT:[nagios][log][command]};%{DATA:[host][hostname]};%{DATA:[service][name]};%{DATA:[service][state]};%{GREEDYDATA:[nagios][log][check_result]}
108 | NAGIOS_EC_LINE_PROCESS_HOST_CHECK_RESULT %{NAGIOS_TYPE_EXTERNAL_COMMAND:[nagios][log][type]}: %{NAGIOS_EC_PROCESS_HOST_CHECK_RESULT:[nagios][log][command]};%{DATA:[host][hostname]};%{DATA:[service][state]};%{GREEDYDATA:[nagios][log][check_result]}
109 |
110 | #Disable host & service notifications
111 | NAGIOS_EC_LINE_DISABLE_HOST_SVC_NOTIFICATIONS %{NAGIOS_TYPE_EXTERNAL_COMMAND:[nagios][log][type]}: %{NAGIOS_EC_DISABLE_HOST_SVC_NOTIFICATIONS:[nagios][log][command]};%{GREEDYDATA:[host][hostname]}
112 | NAGIOS_EC_LINE_DISABLE_HOST_NOTIFICATIONS %{NAGIOS_TYPE_EXTERNAL_COMMAND:[nagios][log][type]}: %{NAGIOS_EC_DISABLE_HOST_NOTIFICATIONS:[nagios][log][command]};%{GREEDYDATA:[host][hostname]}
113 | NAGIOS_EC_LINE_DISABLE_SVC_NOTIFICATIONS %{NAGIOS_TYPE_EXTERNAL_COMMAND:[nagios][log][type]}: %{NAGIOS_EC_DISABLE_SVC_NOTIFICATIONS:[nagios][log][command]};%{DATA:[host][hostname]};%{GREEDYDATA:[service][name]}
114 |
115 | #Enable host & service notifications
116 | NAGIOS_EC_LINE_ENABLE_HOST_SVC_NOTIFICATIONS %{NAGIOS_TYPE_EXTERNAL_COMMAND:[nagios][log][type]}: %{NAGIOS_EC_ENABLE_HOST_SVC_NOTIFICATIONS:[nagios][log][command]};%{GREEDYDATA:[host][hostname]}
117 | NAGIOS_EC_LINE_ENABLE_HOST_NOTIFICATIONS %{NAGIOS_TYPE_EXTERNAL_COMMAND:[nagios][log][type]}: %{NAGIOS_EC_ENABLE_HOST_NOTIFICATIONS:[nagios][log][command]};%{GREEDYDATA:[host][hostname]}
118 | NAGIOS_EC_LINE_ENABLE_SVC_NOTIFICATIONS %{NAGIOS_TYPE_EXTERNAL_COMMAND:[nagios][log][type]}: %{NAGIOS_EC_ENABLE_SVC_NOTIFICATIONS:[nagios][log][command]};%{DATA:[host][hostname]};%{GREEDYDATA:[service][name]}
119 |
120 | #Schedule host & service downtime
121 | NAGIOS_EC_LINE_SCHEDULE_HOST_DOWNTIME %{NAGIOS_TYPE_EXTERNAL_COMMAND:[nagios][log][type]}: %{NAGIOS_EC_SCHEDULE_HOST_DOWNTIME:[nagios][log][command]};%{DATA:[host][hostname]};%{NUMBER:[nagios][log][start_time]};%{NUMBER:[nagios][log][end_time]};%{NUMBER:[nagios][log][fixed]};%{NUMBER:[nagios][log][trigger_id]};%{NUMBER:[nagios][log][duration]:int};%{DATA:[user][name]};%{DATA:[nagios][log][comment]}
122 |
123 | #End matching line
124 | NAGIOSLOGLINE %{NAGIOSTIME} (?:%{NAGIOS_WARNING}|%{NAGIOS_CURRENT_SERVICE_STATE}|%{NAGIOS_CURRENT_HOST_STATE}|%{NAGIOS_SERVICE_NOTIFICATION}|%{NAGIOS_HOST_NOTIFICATION}|%{NAGIOS_SERVICE_ALERT}|%{NAGIOS_HOST_ALERT}|%{NAGIOS_SERVICE_FLAPPING_ALERT}|%{NAGIOS_HOST_FLAPPING_ALERT}|%{NAGIOS_SERVICE_DOWNTIME_ALERT}|%{NAGIOS_HOST_DOWNTIME_ALERT}|%{NAGIOS_PASSIVE_SERVICE_CHECK}|%{NAGIOS_PASSIVE_HOST_CHECK}|%{NAGIOS_SERVICE_EVENT_HANDLER}|%{NAGIOS_HOST_EVENT_HANDLER}|%{NAGIOS_TIMEPERIOD_TRANSITION}|%{NAGIOS_EC_LINE_DISABLE_SVC_CHECK}|%{NAGIOS_EC_LINE_ENABLE_SVC_CHECK}|%{NAGIOS_EC_LINE_DISABLE_HOST_CHECK}|%{NAGIOS_EC_LINE_ENABLE_HOST_CHECK}|%{NAGIOS_EC_LINE_PROCESS_HOST_CHECK_RESULT}|%{NAGIOS_EC_LINE_PROCESS_SERVICE_CHECK_RESULT}|%{NAGIOS_EC_LINE_SCHEDULE_HOST_DOWNTIME}|%{NAGIOS_EC_LINE_DISABLE_HOST_SVC_NOTIFICATIONS}|%{NAGIOS_EC_LINE_ENABLE_HOST_SVC_NOTIFICATIONS}|%{NAGIOS_EC_LINE_DISABLE_HOST_NOTIFICATIONS}|%{NAGIOS_EC_LINE_ENABLE_HOST_NOTIFICATIONS}|%{NAGIOS_EC_LINE_DISABLE_SVC_NOTIFICATIONS}|%{NAGIOS_EC_LINE_ENABLE_SVC_NOTIFICATIONS})
125 |
--------------------------------------------------------------------------------
/public/patterns/postfix:
--------------------------------------------------------------------------------
1 | # Version: 1.0.0
2 |
3 | # common postfix patterns
4 | POSTFIX_QUEUEID ([0-9A-F]{6,}|[0-9a-zA-Z]{12,}|NOQUEUE)
5 | POSTFIX_CLIENT_INFO %{HOSTNAME:postfix_client_hostname}?\[%{IP:postfix_client_ip}\](:%{INT:postfix_client_port})?
6 | POSTFIX_RELAY_INFO %{HOSTNAME:postfix_relay_hostname}?\[(%{IP:postfix_relay_ip}|%{DATA:postfix_relay_service})\](:%{INT:postfix_relay_port})?|%{WORD:postfix_relay_service}
7 | POSTFIX_SMTP_STAGE (CONNECT|HELO|EHLO|STARTTLS|AUTH|MAIL( FROM)?|RCPT( TO)?|(end of )?DATA|RSET|UNKNOWN|END-OF-MESSAGE|VRFY|\.)
8 | POSTFIX_ACTION (accept|defer|discard|filter|header-redirect|reject|reject_warning)
9 | POSTFIX_STATUS_CODE \d{3}
10 | POSTFIX_STATUS_CODE_ENHANCED \d\.\d+\.\d+
11 | POSTFIX_DNSBL_MESSAGE Service unavailable; .* \[%{GREEDYDATA:postfix_status_data}\] %{GREEDYDATA:postfix_status_message};
12 | POSTFIX_PS_ACCESS_ACTION (DISCONNECT|BLACKLISTED|WHITELISTED|WHITELIST VETO|PASS NEW|PASS OLD)
13 | POSTFIX_PS_VIOLATION (BARE NEWLINE|COMMAND (TIME|COUNT|LENGTH) LIMIT|COMMAND PIPELINING|DNSBL|HANGUP|NON-SMTP COMMAND|PREGREET)
14 | POSTFIX_TIME_UNIT %{NUMBER}[smhd]
15 | POSTFIX_KEYVALUE_DATA [\w-]+=[^;]*
16 | POSTFIX_KEYVALUE %{POSTFIX_QUEUEID:postfix_queueid}: %{POSTFIX_KEYVALUE_DATA:postfix_keyvalue_data}
17 | POSTFIX_WARNING_LEVEL (warning|fatal|info)
18 |
19 | POSTFIX_TLSCONN (Anonymous|Trusted|Untrusted|Verified) TLS connection established (to %{POSTFIX_RELAY_INFO}|from %{POSTFIX_CLIENT_INFO}): %{DATA:postfix_tls_version} with cipher %{DATA:postfix_tls_cipher} \(%{DATA:postfix_tls_cipher_size} bits\)
20 | POSTFIX_TLSVERIFICATION certificate verification failed for %{POSTFIX_RELAY_INFO}: %{GREEDYDATA:postfix_tls_error}
21 |
22 | POSTFIX_DELAYS %{NUMBER:postfix_delay_before_qmgr}/%{NUMBER:postfix_delay_in_qmgr}/%{NUMBER:postfix_delay_conn_setup}/%{NUMBER:postfix_delay_transmission}
23 | POSTFIX_LOSTCONN (Connection timed out|No route to host|Connection refused|Network is unreachable|lost connection|timeout|SSL_accept error|-1)
24 | POSTFIX_LOSTCONN_REASONS (receiving the initial server greeting|sending message body|sending end of data -- message may be sent more than once)
25 | POSTFIX_PROXY_MESSAGE (%{POSTFIX_STATUS_CODE:postfix_proxy_status_code} )?(%{POSTFIX_STATUS_CODE_ENHANCED:postfix_proxy_status_code_enhanced})?.*
26 | POSTFIX_COMMAND_COUNTER_DATA (helo=(%{INT:postfix_cmd_helo_accepted}/)?%{INT:postfix_cmd_helo} )?(ehlo=(%{INT:postfix_cmd_ehlo_accepted}/)?%{INT:postfix_cmd_ehlo} )?(starttls=(%{INT:postfix_cmd_starttls_accepted}/)?%{INT:postfix_cmd_starttls} )?(auth=(%{INT:postfix_cmd_auth_accepted}/)?%{INT:postfix_cmd_auth} )?(mail=(%{INT:postfix_cmd_mail_accepted}/)?%{INT:postfix_cmd_mail} )?(rcpt=(%{INT:postfix_cmd_rcpt_accepted}/)?%{INT:postfix_cmd_rcpt} )?(data=(%{INT:postfix_cmd_data_accepted}/)?%{INT:postfix_cmd_data} )?(rset=(%{INT:postfix_cmd_rset_accepted}/)?%{INT:postfix_cmd_rset} )?(quit=(%{INT:postfix_cmd_quit_accepted}/)?%{INT:postfix_cmd_quit} )?(unknown=(%{INT:postfix_cmd_unknown_accepted}/)?%{INT:postfix_cmd_unknown} )?commands=(%{INT:postfix_cmd_count_accepted}/)?%{INT:postfix_cmd_count}
27 |
28 | # helper patterns
29 | GREEDYDATA_NO_COLON [^:]*
30 | GREEDYDATA_NO_SEMICOLON [^;]*
31 | GREEDYDATA_NO_BRACKET [^<>]*
32 | STATUS_WORD [\w-]*
33 |
34 | # warning patterns
35 | POSTFIX_WARNING_WITH_KV (%{POSTFIX_QUEUEID:postfix_queueid}: )?%{POSTFIX_WARNING_LEVEL:postfix_message_level}: (%{POSTFIX_CLIENT_INFO}: )?%{GREEDYDATA:postfix_message}; %{POSTFIX_KEYVALUE_DATA:postfix_keyvalue_data}
36 | POSTFIX_WARNING_WITHOUT_KV (%{POSTFIX_QUEUEID:postfix_queueid}: )?%{POSTFIX_WARNING_LEVEL:postfix_message_level}: (%{POSTFIX_CLIENT_INFO}: )?%{GREEDYDATA:postfix_message}
37 | POSTFIX_WARNING %{POSTFIX_WARNING_WITH_KV}|%{POSTFIX_WARNING_WITHOUT_KV}
38 |
39 | # smtpd patterns
40 | POSTFIX_SMTPD_CONNECT connect from %{POSTFIX_CLIENT_INFO}
41 | POSTFIX_SMTPD_DISCONNECT disconnect from %{POSTFIX_CLIENT_INFO}( %{GREEDYDATA:postfix_command_counter_data})?
42 | POSTFIX_SMTPD_LOSTCONN %{POSTFIX_LOSTCONN:postfix_smtpd_lostconn_data}( after %{POSTFIX_SMTP_STAGE:postfix_smtp_stage}( \(%{INT} bytes\))?)? from %{POSTFIX_CLIENT_INFO}(: %{GREEDYDATA:postfix_smtpd_lostconn_reason})?
43 | POSTFIX_SMTPD_NOQUEUE %{POSTFIX_QUEUEID:postfix_queueid}: %{POSTFIX_ACTION:postfix_action}: %{POSTFIX_SMTP_STAGE:postfix_smtp_stage} from %{POSTFIX_CLIENT_INFO}:( %{POSTFIX_STATUS_CODE:postfix_status_code} %{POSTFIX_STATUS_CODE_ENHANCED:postfix_status_code_enhanced})?( <%{DATA:postfix_status_data}>:)? (%{POSTFIX_DNSBL_MESSAGE}|%{GREEDYDATA:postfix_status_message};) %{POSTFIX_KEYVALUE_DATA:postfix_keyvalue_data}
44 | POSTFIX_SMTPD_PIPELINING improper command pipelining after %{POSTFIX_SMTP_STAGE:postfix_smtp_stage} from %{POSTFIX_CLIENT_INFO}: %{GREEDYDATA:postfix_improper_pipelining_data}
45 | POSTFIX_SMTPD_PROXY proxy-%{POSTFIX_ACTION:postfix_proxy_result}: (%{POSTFIX_SMTP_STAGE:postfix_proxy_smtp_stage}): %{POSTFIX_PROXY_MESSAGE:postfix_proxy_message}; %{POSTFIX_KEYVALUE_DATA:postfix_keyvalue_data}
46 |
47 | # cleanup patterns
48 | POSTFIX_CLEANUP_MILTER %{POSTFIX_QUEUEID:postfix_queueid}: milter-%{POSTFIX_ACTION:postfix_milter_result}: %{GREEDYDATA:postfix_milter_message}; %{GREEDYDATA_NO_COLON:postfix_keyvalue_data}(: %{GREEDYDATA:postfix_milter_data})?
49 | POSTFIX_CLEANUP_PREPEND_TYPE (header|body)
50 | POSTFIX_CLEANUP_PREPEND %{POSTFIX_QUEUEID:postfix_queueid}: prepend: %{POSTFIX_CLEANUP_PREPEND_TYPE:postfix_prepend_type} %{GREEDYDATA:postfix_prepend_trigger} from %{POSTFIX_CLIENT_INFO}; %{GREEDYDATA_NO_COLON:postfix_keyvalue_data}: %{GREEDYDATA:postfix_prepend_value}
51 | POSTFIX_CLEANUP_MESSAGEID %{POSTFIX_QUEUEID:postfix_queueid}: message-id=%{GREEDYDATA_NO_BRACKET:postfix_message-id}>?
52 |
53 | # qmgr patterns
54 | POSTFIX_QMGR_REMOVED %{POSTFIX_QUEUEID:postfix_queueid}: removed
55 | POSTFIX_QMGR_ACTIVE %{POSTFIX_QUEUEID:postfix_queueid}: %{POSTFIX_KEYVALUE_DATA:postfix_keyvalue_data} \(queue active\)
56 | POSTFIX_QMGR_EXPIRED %{POSTFIX_QUEUEID:postfix_queueid}: from=<%{DATA:postfix_from}>, status=%{STATUS_WORD:postfix_status}, returned to sender
57 |
58 | # pipe patterns
59 | POSTFIX_PIPE_ANY %{POSTFIX_QUEUEID:postfix_queueid}: %{POSTFIX_KEYVALUE_DATA:postfix_keyvalue_data}, status=%{STATUS_WORD:postfix_status} \(%{GREEDYDATA:postfix_pipe_response}\)
60 |
61 | # error patterns
62 | POSTFIX_ERROR_ANY %{POSTFIX_QUEUEID:postfix_queueid}: %{POSTFIX_KEYVALUE_DATA:postfix_keyvalue_data}, status=%{STATUS_WORD:postfix_status} \(%{GREEDYDATA:postfix_error_response}\)
63 |
64 | # discard patterns
65 | POSTFIX_DISCARD_ANY %{POSTFIX_QUEUEID:postfix_queueid}: %{POSTFIX_KEYVALUE_DATA:postfix_keyvalue_data} status=%{STATUS_WORD:postfix_status} %{GREEDYDATA}
66 |
67 | # postsuper patterns
68 | POSTFIX_POSTSUPER_ACTIONS (removed|requeued|placed on hold|released from hold)
69 | POSTFIX_POSTSUPER_ACTION %{POSTFIX_QUEUEID:postfix_queueid}: %{POSTFIX_POSTSUPER_ACTIONS:postfix_postsuper_action}
70 | POSTFIX_POSTSUPER_SUMMARY_ACTIONS (Deleted|Requeued|Placed on hold|Released from hold)
71 | POSTFIX_POSTSUPER_SUMMARY %{POSTFIX_POSTSUPER_SUMMARY_ACTIONS:postfix_postsuper_summary_action}: %{NUMBER:postfix_postsuper_summary_count} messages?
72 |
73 | # postscreen patterns
74 | POSTFIX_PS_CONNECT CONNECT from %{POSTFIX_CLIENT_INFO} to \[%{IP:postfix_server_ip}\]:%{INT:postfix_server_port}
75 | POSTFIX_PS_ACCESS %{POSTFIX_PS_ACCESS_ACTION:postfix_postscreen_access} %{POSTFIX_CLIENT_INFO}
76 | POSTFIX_PS_NOQUEUE %{POSTFIX_SMTPD_NOQUEUE}
77 | POSTFIX_PS_TOOBUSY NOQUEUE: reject: CONNECT from %{POSTFIX_CLIENT_INFO}: %{GREEDYDATA:postfix_postscreen_toobusy_data}
78 | POSTFIX_PS_DNSBL %{POSTFIX_PS_VIOLATION:postfix_postscreen_violation} rank %{INT:postfix_postscreen_dnsbl_rank} for %{POSTFIX_CLIENT_INFO}
79 | POSTFIX_PS_CACHE cache %{DATA} full cleanup: retained=%{NUMBER:postfix_postscreen_cache_retained} dropped=%{NUMBER:postfix_postscreen_cache_dropped} entries
80 | POSTFIX_PS_VIOLATIONS %{POSTFIX_PS_VIOLATION:postfix_postscreen_violation}( %{INT})?( after %{NUMBER:postfix_postscreen_violation_time})? from %{POSTFIX_CLIENT_INFO}(( after %{POSTFIX_SMTP_STAGE:postfix_smtp_stage})?(: %{GREEDYDATA:postfix_postscreen_data})?| in tests (after|before) SMTP handshake)
81 |
82 | # dnsblog patterns
83 | POSTFIX_DNSBLOG_LISTING addr %{IP:postfix_client_ip} listed by domain %{HOSTNAME:postfix_dnsbl_domain} as %{IP:postfix_dnsbl_result}
84 |
85 | # tlsproxy patterns
86 | POSTFIX_TLSPROXY_CONN (DIS)?CONNECT( from)? %{POSTFIX_CLIENT_INFO}
87 |
88 | # anvil patterns
89 | POSTFIX_ANVIL_CONN_RATE statistics: max connection rate %{NUMBER:postfix_anvil_conn_rate}/%{POSTFIX_TIME_UNIT:postfix_anvil_conn_period} for \(%{DATA:postfix_service}:%{IP:postfix_client_ip}\) at %{SYSLOGTIMESTAMP:postfix_anvil_timestamp}
90 | POSTFIX_ANVIL_CONN_CACHE statistics: max cache size %{NUMBER:postfix_anvil_cache_size} at %{SYSLOGTIMESTAMP:postfix_anvil_timestamp}
91 | POSTFIX_ANVIL_CONN_COUNT statistics: max connection count %{NUMBER:postfix_anvil_conn_count} for \(%{DATA:postfix_service}:%{IP:postfix_client_ip}\) at %{SYSLOGTIMESTAMP:postfix_anvil_timestamp}
92 |
93 | # smtp patterns
94 | POSTFIX_SMTP_DELIVERY %{POSTFIX_KEYVALUE} status=%{STATUS_WORD:postfix_status}( \(%{GREEDYDATA:postfix_smtp_response}\))?
95 | POSTFIX_SMTP_CONNERR connect to %{POSTFIX_RELAY_INFO}: %{POSTFIX_LOSTCONN:postfix_smtp_lostconn_data}
96 | POSTFIX_SMTP_SSLCONNERR SSL_connect error to %{POSTFIX_RELAY_INFO}: %{POSTFIX_LOSTCONN:postfix_smtp_lostconn_data}
97 | POSTFIX_SMTP_LOSTCONN %{POSTFIX_QUEUEID:postfix_queueid}: %{POSTFIX_LOSTCONN:postfix_smtp_lostconn_data} with %{POSTFIX_RELAY_INFO}( while %{POSTFIX_LOSTCONN_REASONS:postfix_smtp_lostconn_reason})?
98 | POSTFIX_SMTP_TIMEOUT %{POSTFIX_QUEUEID:postfix_queueid}: conversation with %{POSTFIX_RELAY_INFO} timed out( while %{POSTFIX_LOSTCONN_REASONS:postfix_smtp_lostconn_reason})?
99 | POSTFIX_SMTP_RELAYERR %{POSTFIX_QUEUEID:postfix_queueid}: host %{POSTFIX_RELAY_INFO} said: %{GREEDYDATA:postfix_smtp_response} \(in reply to %{POSTFIX_SMTP_STAGE:postfix_smtp_stage} command\)
100 | POSTFIX_SMTP_UTF8 host %{POSTFIX_RELAY_INFO} offers SMTPUTF8 support, but not 8BITMIME
101 | POSTFIX_SMTP_PIX %{POSTFIX_QUEUEID:postfix_queueid}: enabling PIX workarounds: %{DATA:postfix_pix_workaround} for %{POSTFIX_RELAY_INFO}
102 |
103 | # master patterns
104 | POSTFIX_MASTER_START (daemon started|reload) -- version %{DATA:postfix_version}, configuration %{PATH:postfix_config_path}
105 | POSTFIX_MASTER_EXIT terminating on signal %{INT:postfix_termination_signal}
106 |
107 | # bounce patterns
108 | POSTFIX_BOUNCE_NOTIFICATION %{POSTFIX_QUEUEID:postfix_queueid}: sender (non-delivery|delivery status|delay) notification: %{POSTFIX_QUEUEID:postfix_bounce_queueid}
109 |
110 | # scache patterns
111 | POSTFIX_SCACHE_LOOKUPS statistics: (address|domain) lookup hits=%{INT:postfix_scache_hits} miss=%{INT:postfix_scache_miss} success=%{INT:postfix_scache_success}%
112 | POSTFIX_SCACHE_SIMULTANEOUS statistics: max simultaneous domains=%{INT:postfix_scache_domains} addresses=%{INT:postfix_scache_addresses} connection=%{INT:postfix_scache_connection}
113 | POSTFIX_SCACHE_TIMESTAMP statistics: start interval %{SYSLOGTIMESTAMP:postfix_scache_timestamp}
114 |
115 | # aggregate all patterns
116 | POSTFIX_SMTPD %{POSTFIX_SMTPD_CONNECT}|%{POSTFIX_SMTPD_DISCONNECT}|%{POSTFIX_SMTPD_LOSTCONN}|%{POSTFIX_SMTPD_NOQUEUE}|%{POSTFIX_SMTPD_PIPELINING}|%{POSTFIX_TLSCONN}|%{POSTFIX_WARNING}|%{POSTFIX_SMTPD_PROXY}|%{POSTFIX_KEYVALUE}
117 | POSTFIX_CLEANUP %{POSTFIX_CLEANUP_MESSAGEID}|%{POSTFIX_CLEANUP_MILTER}|%{POSTFIX_CLEANUP_PREPEND}|%{POSTFIX_WARNING}|%{POSTFIX_KEYVALUE}
118 | POSTFIX_QMGR %{POSTFIX_QMGR_REMOVED}|%{POSTFIX_QMGR_ACTIVE}|%{POSTFIX_QMGR_EXPIRED}|%{POSTFIX_WARNING}
119 | POSTFIX_PIPE %{POSTFIX_PIPE_ANY}
120 | POSTFIX_POSTSCREEN %{POSTFIX_PS_CONNECT}|%{POSTFIX_PS_ACCESS}|%{POSTFIX_PS_NOQUEUE}|%{POSTFIX_PS_TOOBUSY}|%{POSTFIX_PS_CACHE}|%{POSTFIX_PS_DNSBL}|%{POSTFIX_PS_VIOLATIONS}|%{POSTFIX_WARNING}
121 | POSTFIX_DNSBLOG %{POSTFIX_DNSBLOG_LISTING}|%{POSTFIX_WARNING}
122 | POSTFIX_ANVIL %{POSTFIX_ANVIL_CONN_RATE}|%{POSTFIX_ANVIL_CONN_CACHE}|%{POSTFIX_ANVIL_CONN_COUNT}
123 | POSTFIX_SMTP %{POSTFIX_SMTP_DELIVERY}|%{POSTFIX_SMTP_CONNERR}|%{POSTFIX_SMTP_SSLCONNERR}|%{POSTFIX_SMTP_LOSTCONN}|%{POSTFIX_SMTP_TIMEOUT}|%{POSTFIX_SMTP_RELAYERR}|%{POSTFIX_TLSCONN}|%{POSTFIX_WARNING}|%{POSTFIX_SMTP_UTF8}|%{POSTFIX_TLSVERIFICATION}|%{POSTFIX_SMTP_PIX}
124 | POSTFIX_DISCARD %{POSTFIX_DISCARD_ANY}|%{POSTFIX_WARNING}
125 | POSTFIX_LMTP %{POSTFIX_SMTP}
126 | POSTFIX_PICKUP %{POSTFIX_KEYVALUE}
127 | POSTFIX_TLSPROXY %{POSTFIX_TLSPROXY_CONN}|%{POSTFIX_WARNING}
128 | POSTFIX_MASTER %{POSTFIX_MASTER_START}|%{POSTFIX_MASTER_EXIT}|%{POSTFIX_WARNING}
129 | POSTFIX_BOUNCE %{POSTFIX_BOUNCE_NOTIFICATION}
130 | POSTFIX_SENDMAIL %{POSTFIX_WARNING}
131 | POSTFIX_POSTDROP %{POSTFIX_WARNING}
132 | POSTFIX_SCACHE %{POSTFIX_SCACHE_LOOKUPS}|%{POSTFIX_SCACHE_SIMULTANEOUS}|%{POSTFIX_SCACHE_TIMESTAMP}
133 | POSTFIX_TRIVIAL_REWRITE %{POSTFIX_WARNING}
134 | POSTFIX_TLSMGR %{POSTFIX_WARNING}
135 | POSTFIX_LOCAL %{POSTFIX_KEYVALUE}|%{POSTFIX_WARNING}
136 | POSTFIX_VIRTUAL %{POSTFIX_SMTP_DELIVERY}
137 | POSTFIX_ERROR %{POSTFIX_ERROR_ANY}
138 | POSTFIX_POSTSUPER %{POSTFIX_POSTSUPER_ACTION}|%{POSTFIX_POSTSUPER_SUMMARY}
--------------------------------------------------------------------------------
/src/codemirror/codemirror.css:
--------------------------------------------------------------------------------
1 | /* BASICS */
2 |
3 | .CodeMirror {
4 | /* Set height, width, borders, and global font properties here */
5 | font-family: monospace;
6 | min-height: 100%;
7 | color: black;
8 | direction: ltr;
9 | font-size: 1.25rem;
10 | height: 100%;
11 | }
12 |
13 | /* PADDING */
14 |
15 | .CodeMirror-lines {
16 | padding: 4px 0; /* Vertical padding around content */
17 | }
18 | .CodeMirror pre.CodeMirror-line,
19 | .CodeMirror pre.CodeMirror-line-like {
20 | padding: 0 4px; /* Horizontal padding of content */
21 | }
22 |
23 | .CodeMirror-scrollbar-filler,
24 | .CodeMirror-gutter-filler {
25 | background-color: white; /* The little square between H and V scrollbars */
26 | }
27 |
28 | /* GUTTER */
29 |
30 | .CodeMirror-gutters {
31 | border-right: 1px solid #ddd;
32 | background-color: #f7f7f7;
33 | white-space: nowrap;
34 | }
35 | .CodeMirror-linenumbers {
36 | }
37 | .CodeMirror-linenumber {
38 | padding: 0 3px 0 5px;
39 | min-width: 20px;
40 | text-align: right;
41 | color: #999;
42 | white-space: nowrap;
43 | }
44 |
45 | .CodeMirror-guttermarker {
46 | color: black;
47 | }
48 | .CodeMirror-guttermarker-subtle {
49 | color: #999;
50 | }
51 |
52 | /* CURSOR */
53 |
54 | .CodeMirror-cursor {
55 | border-left: 1px solid black;
56 | border-right: none;
57 | width: 0;
58 | }
59 | /* Shown when moving in bi-directional text */
60 | .CodeMirror div.CodeMirror-secondarycursor {
61 | border-left: 1px solid silver;
62 | }
63 | .cm-fat-cursor .CodeMirror-cursor {
64 | width: auto;
65 | border: 0 !important;
66 | background: #7e7;
67 | }
68 | .cm-fat-cursor div.CodeMirror-cursors {
69 | z-index: 1;
70 | }
71 | .cm-fat-cursor-mark {
72 | background-color: rgba(20, 255, 20, 0.5);
73 | -webkit-animation: blink 1.06s steps(1) infinite;
74 | -moz-animation: blink 1.06s steps(1) infinite;
75 | animation: blink 1.06s steps(1) infinite;
76 | }
77 | .cm-animate-fat-cursor {
78 | width: auto;
79 | border: 0;
80 | -webkit-animation: blink 1.06s steps(1) infinite;
81 | -moz-animation: blink 1.06s steps(1) infinite;
82 | animation: blink 1.06s steps(1) infinite;
83 | background-color: #7e7;
84 | }
85 | @-moz-keyframes blink {
86 | 0% {
87 | }
88 | 50% {
89 | background-color: transparent;
90 | }
91 | 100% {
92 | }
93 | }
94 | @-webkit-keyframes blink {
95 | 0% {
96 | }
97 | 50% {
98 | background-color: transparent;
99 | }
100 | 100% {
101 | }
102 | }
103 | @keyframes blink {
104 | 0% {
105 | }
106 | 50% {
107 | background-color: transparent;
108 | }
109 | 100% {
110 | }
111 | }
112 |
113 | /* Can style cursor different in overwrite (non-insert) mode */
114 | .CodeMirror-overwrite .CodeMirror-cursor {
115 | }
116 |
117 | .cm-tab {
118 | display: inline-block;
119 | text-decoration: inherit;
120 | }
121 |
122 | .CodeMirror-rulers {
123 | position: absolute;
124 | left: 0;
125 | right: 0;
126 | top: -50px;
127 | bottom: 0;
128 | overflow: hidden;
129 | }
130 | .CodeMirror-ruler {
131 | border-left: 1px solid #ccc;
132 | top: 0;
133 | bottom: 0;
134 | position: absolute;
135 | }
136 |
137 | /* DEFAULT THEME */
138 |
139 | .cm-s-default .cm-header {
140 | color: blue;
141 | }
142 | .cm-s-default .cm-quote {
143 | color: #090;
144 | }
145 | .cm-negative {
146 | color: #d44;
147 | }
148 | .cm-positive {
149 | color: #292;
150 | }
151 | .cm-header,
152 | .cm-strong {
153 | font-weight: bold;
154 | }
155 | .cm-em {
156 | font-style: italic;
157 | }
158 | .cm-link {
159 | text-decoration: underline;
160 | }
161 | .cm-strikethrough {
162 | text-decoration: line-through;
163 | }
164 |
165 | .cm-s-default .cm-keyword {
166 | color: #708;
167 | }
168 | .cm-s-default .cm-atom {
169 | color: #219;
170 | }
171 | .cm-s-default .cm-number {
172 | color: #164;
173 | }
174 | .cm-s-default .cm-def {
175 | color: #00f;
176 | }
177 | .cm-s-default .cm-variable,
178 | .cm-s-default .cm-punctuation,
179 | .cm-s-default .cm-property,
180 | .cm-s-default .cm-operator {
181 | }
182 | .cm-s-default .cm-variable-2 {
183 | color: #05a;
184 | }
185 | .cm-s-default .cm-variable-3,
186 | .cm-s-default .cm-type {
187 | color: #085;
188 | }
189 | .cm-s-default .cm-comment {
190 | color: #a50;
191 | }
192 | .cm-s-default .cm-string {
193 | color: #a11;
194 | }
195 | .cm-s-default .cm-string-2 {
196 | color: #f50;
197 | }
198 | .cm-s-default .cm-meta {
199 | color: #555;
200 | }
201 | .cm-s-default .cm-qualifier {
202 | color: #555;
203 | }
204 | .cm-s-default .cm-builtin {
205 | color: #30a;
206 | }
207 | .cm-s-default .cm-bracket {
208 | color: #997;
209 | }
210 | .cm-s-default .cm-tag {
211 | color: #170;
212 | }
213 | .cm-s-default .cm-attribute {
214 | color: #00c;
215 | }
216 | .cm-s-default .cm-hr {
217 | color: #999;
218 | }
219 | .cm-s-default .cm-link {
220 | color: #00c;
221 | }
222 |
223 | .cm-s-default .cm-error {
224 | color: #f00;
225 | }
226 | .cm-invalidchar {
227 | color: #f00;
228 | }
229 |
230 | .CodeMirror-composing {
231 | border-bottom: 2px solid;
232 | }
233 |
234 | /* Default styles for common addons */
235 |
236 | div.CodeMirror span.CodeMirror-matchingbracket {
237 | color: #0b0;
238 | }
239 | div.CodeMirror span.CodeMirror-nonmatchingbracket {
240 | color: #a22;
241 | }
242 | .CodeMirror-matchingtag {
243 | background: rgba(255, 150, 0, 0.3);
244 | }
245 | .CodeMirror-activeline-background {
246 | background: #e8f2ff;
247 | }
248 |
249 | /* STOP */
250 |
251 | /* The rest of this file contains styles related to the mechanics of
252 | the editor. You probably shouldn't touch them. */
253 |
254 | .CodeMirror {
255 | position: relative;
256 | overflow: hidden;
257 | background: white;
258 | }
259 |
260 | .CodeMirror-scroll {
261 | overflow: scroll !important; /* Things will break if this is overridden */
262 | /* 50px is the magic margin used to hide the element's real scrollbars */
263 | /* See overflow: hidden in .CodeMirror */
264 | margin-bottom: -50px;
265 | margin-right: -50px;
266 | padding-bottom: 50px;
267 | height: 100%;
268 | outline: none; /* Prevent dragging from highlighting the element */
269 | position: relative;
270 | }
271 | .CodeMirror-sizer {
272 | position: relative;
273 | border-right: 50px solid transparent;
274 | }
275 |
276 | /* The fake, visible scrollbars. Used to force redraw during scrolling
277 | before actual scrolling happens, thus preventing shaking and
278 | flickering artifacts. */
279 | .CodeMirror-vscrollbar,
280 | .CodeMirror-hscrollbar,
281 | .CodeMirror-scrollbar-filler,
282 | .CodeMirror-gutter-filler {
283 | position: absolute;
284 | z-index: 6;
285 | display: none;
286 | outline: none;
287 | }
288 | .CodeMirror-vscrollbar {
289 | right: 0;
290 | top: 0;
291 | overflow-x: hidden;
292 | overflow-y: scroll;
293 | }
294 | .CodeMirror-hscrollbar {
295 | bottom: 0;
296 | left: 0;
297 | overflow-y: hidden;
298 | overflow-x: scroll;
299 | }
300 | .CodeMirror-scrollbar-filler {
301 | right: 0;
302 | bottom: 0;
303 | }
304 | .CodeMirror-gutter-filler {
305 | left: 0;
306 | bottom: 0;
307 | }
308 |
309 | .CodeMirror-gutters {
310 | position: absolute;
311 | left: 0;
312 | top: 0;
313 | min-height: 100%;
314 | z-index: 3;
315 | }
316 | .CodeMirror-gutter {
317 | white-space: normal;
318 | height: 100%;
319 | display: inline-block;
320 | vertical-align: top;
321 | margin-bottom: -50px;
322 | }
323 | .CodeMirror-gutter-wrapper {
324 | position: absolute;
325 | z-index: 4;
326 | background: none !important;
327 | border: none !important;
328 | }
329 | .CodeMirror-gutter-background {
330 | position: absolute;
331 | top: 0;
332 | bottom: 0;
333 | z-index: 4;
334 | }
335 | .CodeMirror-gutter-elt {
336 | position: absolute;
337 | cursor: default;
338 | z-index: 4;
339 | }
340 | .CodeMirror-gutter-wrapper ::selection {
341 | background-color: transparent;
342 | }
343 | .CodeMirror-gutter-wrapper ::-moz-selection {
344 | background-color: transparent;
345 | }
346 |
347 | .CodeMirror-lines {
348 | cursor: text;
349 | min-height: 1px; /* prevents collapsing before first draw */
350 | }
351 | .CodeMirror pre.CodeMirror-line,
352 | .CodeMirror pre.CodeMirror-line-like {
353 | /* Reset some styles that the rest of the page might have set */
354 | -moz-border-radius: 0;
355 | -webkit-border-radius: 0;
356 | border-radius: 0;
357 | border-width: 0;
358 | background: transparent;
359 | font-family: inherit;
360 | font-size: inherit;
361 | margin: 0;
362 | white-space: pre;
363 | word-wrap: normal;
364 | line-height: inherit;
365 | color: inherit;
366 | z-index: 2;
367 | position: relative;
368 | overflow: visible;
369 | -webkit-tap-highlight-color: transparent;
370 | -webkit-font-variant-ligatures: contextual;
371 | font-variant-ligatures: contextual;
372 | }
373 | .CodeMirror-wrap pre.CodeMirror-line,
374 | .CodeMirror-wrap pre.CodeMirror-line-like {
375 | word-wrap: break-word;
376 | white-space: pre-wrap;
377 | word-break: normal;
378 | }
379 |
380 | .CodeMirror-linebackground {
381 | position: absolute;
382 | left: 0;
383 | right: 0;
384 | top: 0;
385 | bottom: 0;
386 | z-index: 0;
387 | }
388 |
389 | .CodeMirror-linewidget {
390 | position: relative;
391 | z-index: 2;
392 | padding: 0.1px; /* Force widget margins to stay inside of the container */
393 | }
394 |
395 | .CodeMirror-widget {
396 | }
397 |
398 | .CodeMirror-rtl pre {
399 | direction: rtl;
400 | }
401 |
402 | .CodeMirror-code {
403 | outline: none;
404 | }
405 |
406 | /* Force content-box sizing for the elements where we expect it */
407 | .CodeMirror-scroll,
408 | .CodeMirror-sizer,
409 | .CodeMirror-gutter,
410 | .CodeMirror-gutters,
411 | .CodeMirror-linenumber {
412 | -moz-box-sizing: content-box;
413 | box-sizing: content-box;
414 | }
415 |
416 | .CodeMirror-measure {
417 | position: absolute;
418 | width: 100%;
419 | height: 0;
420 | overflow: hidden;
421 | visibility: hidden;
422 | }
423 |
424 | .CodeMirror-cursor {
425 | position: absolute;
426 | pointer-events: none;
427 | }
428 | .CodeMirror-measure pre {
429 | position: static;
430 | }
431 |
432 | div.CodeMirror-cursors {
433 | visibility: hidden;
434 | position: relative;
435 | z-index: 3;
436 | }
437 | div.CodeMirror-dragcursors {
438 | visibility: visible;
439 | }
440 |
441 | .CodeMirror-focused div.CodeMirror-cursors {
442 | visibility: visible;
443 | }
444 |
445 | .CodeMirror-selected {
446 | background: #d9d9d9;
447 | }
448 | .CodeMirror-focused .CodeMirror-selected {
449 | background: #d7d4f0;
450 | }
451 | .CodeMirror-crosshair {
452 | cursor: crosshair;
453 | }
454 | .CodeMirror-line::selection,
455 | .CodeMirror-line > span::selection,
456 | .CodeMirror-line > span > span::selection {
457 | background: #d7d4f0;
458 | }
459 | .CodeMirror-line::-moz-selection,
460 | .CodeMirror-line > span::-moz-selection,
461 | .CodeMirror-line > span > span::-moz-selection {
462 | background: #d7d4f0;
463 | }
464 |
465 | .cm-searching {
466 | background-color: #ffa;
467 | background-color: rgba(255, 255, 0, 0.4);
468 | }
469 |
470 | /* Used to force a border model for a node */
471 | .cm-force-border {
472 | padding-right: 0.1px;
473 | }
474 |
475 | @media print {
476 | /* Hide the cursor when printing */
477 | .CodeMirror div.CodeMirror-cursors {
478 | visibility: hidden;
479 | }
480 | }
481 |
482 | /* See issue #2901 */
483 | .cm-tab-wrap-hack:after {
484 | content: '';
485 | }
486 |
487 | /* Help users use markselection to safely style text background */
488 | span.CodeMirror-selectedtext {
489 | background: none;
490 | }
491 |
492 | .cm-s-material.CodeMirror {
493 | background-color: #263238;
494 | color: #eeffff;
495 | }
496 |
497 | .cm-s-material .CodeMirror-gutters {
498 | background: #263238;
499 | color: #546e7a;
500 | border: none;
501 | }
502 |
503 | .cm-s-material .CodeMirror-guttermarker,
504 | .cm-s-material .CodeMirror-guttermarker-subtle,
505 | .cm-s-material .CodeMirror-linenumber {
506 | color: #546e7a;
507 | }
508 |
509 | .cm-s-material .CodeMirror-cursor {
510 | border-left: 1px solid #ffcc00;
511 | }
512 |
513 | .cm-s-material div.CodeMirror-selected {
514 | background: rgba(128, 203, 196, 0.2);
515 | }
516 |
517 | .cm-s-material.CodeMirror-focused div.CodeMirror-selected {
518 | background: rgba(128, 203, 196, 0.2);
519 | }
520 |
521 | .cm-s-material .CodeMirror-line::selection,
522 | .cm-s-material .CodeMirror-line > span::selection,
523 | .cm-s-material .CodeMirror-line > span > span::selection {
524 | background: rgba(128, 203, 196, 0.2);
525 | }
526 |
527 | .cm-s-material .CodeMirror-line::-moz-selection,
528 | .cm-s-material .CodeMirror-line > span::-moz-selection,
529 | .cm-s-material .CodeMirror-line > span > span::-moz-selection {
530 | background: rgba(128, 203, 196, 0.2);
531 | }
532 |
533 | .cm-s-material .CodeMirror-activeline-background {
534 | background: rgba(0, 0, 0, 0.5);
535 | }
536 |
537 | .cm-s-material .cm-keyword {
538 | color: #c792ea;
539 | }
540 |
541 | .cm-s-material .cm-operator {
542 | color: #89ddff;
543 | }
544 |
545 | .cm-s-material .cm-variable-2 {
546 | color: #eeffff;
547 | }
548 |
549 | .cm-s-material .cm-variable-3,
550 | .cm-s-material .cm-type {
551 | color: #f07178;
552 | }
553 |
554 | .cm-s-material .cm-builtin {
555 | color: #ffcb6b;
556 | }
557 |
558 | .cm-s-material .cm-atom {
559 | color: #f78c6c;
560 | }
561 |
562 | .cm-s-material .cm-number {
563 | color: #ff5370;
564 | }
565 |
566 | .cm-s-material .cm-def {
567 | color: #82aaff;
568 | }
569 |
570 | .cm-s-material .cm-string {
571 | color: #c3e88d;
572 | }
573 |
574 | .cm-s-material .cm-string-2 {
575 | color: #f07178;
576 | }
577 |
578 | .cm-s-material .cm-comment {
579 | color: #546e7a;
580 | }
581 |
582 | .cm-s-material .cm-variable {
583 | color: #f07178;
584 | }
585 |
586 | .cm-s-material .cm-tag {
587 | color: #ff5370;
588 | }
589 |
590 | .cm-s-material .cm-meta {
591 | color: #ffcb6b;
592 | }
593 |
594 | .cm-s-material .cm-attribute {
595 | color: #c792ea;
596 | }
597 |
598 | .cm-s-material .cm-property {
599 | color: #c792ea;
600 | }
601 |
602 | .cm-s-material .cm-qualifier {
603 | color: #decb6b;
604 | }
605 |
606 | .cm-s-material .cm-variable-3,
607 | .cm-s-material .cm-type {
608 | color: #decb6b;
609 | }
610 |
611 | .cm-s-material .cm-error {
612 | color: rgba(255, 255, 255, 1);
613 | background-color: #ff5370;
614 | }
615 |
616 | .cm-s-material .CodeMirror-matchingbracket {
617 | text-decoration: underline;
618 | color: white !important;
619 | }
620 |
621 | .CodeMirror-hints {
622 | position: absolute;
623 | z-index: 10;
624 | overflow: hidden;
625 | list-style: none;
626 |
627 | margin: 0;
628 | padding: 2px;
629 |
630 | -webkit-box-shadow: 2px 3px 5px rgba(0, 0, 0, 0.2);
631 | -moz-box-shadow: 2px 3px 5px rgba(0, 0, 0, 0.2);
632 | box-shadow: 2px 3px 5px rgba(0, 0, 0, 0.2);
633 | border-radius: 3px;
634 | border: 1px solid white;
635 |
636 | background: #555;
637 | font-size: 1rem;
638 | font-family: monospace;
639 |
640 | max-height: 30em;
641 | overflow-y: auto;
642 | }
643 |
644 | .CodeMirror-hint {
645 | margin: 0;
646 | padding: 0 4px;
647 | border-radius: 2px;
648 | white-space: pre;
649 | color: #fff;
650 | cursor: pointer;
651 | }
652 |
653 | li.CodeMirror-hint-active {
654 | background: #08f;
655 | color: white;
656 | }
657 |
--------------------------------------------------------------------------------
/public/patterns/firewalls:
--------------------------------------------------------------------------------
1 | # NetScreen firewall logs
2 | NETSCREENSESSIONLOG %{SYSLOGTIMESTAMP:timestamp} %{IPORHOST:[observer][hostname]} %{NOTSPACE:[observer][name]}: (?<[observer][product]>NetScreen) device_id=%{WORD:[netscreen][device_id]} .*?(system-\w+-%{NONNEGINT:[event][code]}\(%{WORD:[netscreen][session][type]}\))?: start_time="%{DATA:[netscreen][session][start_time]}" duration=%{INT:[netscreen][session][duration]:int} policy_id=%{INT:[netscreen][policy_id]} service=%{DATA:[netscreen][service]} proto=%{INT:[netscreen][protocol_number]:int} src zone=%{WORD:[observer][ingress][zone]} dst zone=%{WORD:[observer][egress][zone]} action=%{WORD:[event][action]} sent=%{INT:[source][bytes]:int} rcvd=%{INT:[destination][bytes]:int} src=%{IPORHOST:[source][address]} dst=%{IPORHOST:[destination][address]}(?: src_port=%{INT:[source][port]:int} dst_port=%{INT:[destination][port]:int})?(?: src-xlated ip=%{IP:[source][nat][ip]} port=%{INT:[source][nat][port]:int} dst-xlated ip=%{IP:[destination][nat][ip]} port=%{INT:[destination][nat][port]:int})?(?: session_id=%{INT:[netscreen][session][id]} reason=%{GREEDYDATA:[netscreen][session][reason]})?
3 | # :long - %{INT:[source][bytes]:int}
4 | # :long - %{INT:[destination][bytes]:int}
5 |
6 | #== Cisco ASA ==
7 | CISCO_TAGGED_SYSLOG ^<%{POSINT:[log][syslog][priority]:int}>%{CISCOTIMESTAMP:timestamp}( %{SYSLOGHOST:[host][hostname]})? ?: %%{CISCOTAG:[cisco][asa][tag]}:
8 | CISCOTIMESTAMP %{MONTH} +%{MONTHDAY}(?: %{YEAR})? %{TIME}
9 | CISCOTAG [A-Z0-9]+-%{INT}-(?:[A-Z0-9_]+)
10 | # Common Particles
11 | CISCO_ACTION Built|Teardown|Deny|Denied|denied|requested|permitted|denied by ACL|discarded|est-allowed|Dropping|created|deleted
12 | CISCO_REASON Duplicate TCP SYN|Failed to locate egress interface|Invalid transport field|No matching connection|DNS Response|DNS Query|(?:%{WORD}\s*)*
13 | CISCO_DIRECTION Inbound|inbound|Outbound|outbound
14 | CISCO_INTERVAL first hit|%{INT}-second interval
15 | CISCO_XLATE_TYPE static|dynamic
16 | # helpers
17 | CISCO_HITCOUNT_INTERVAL hit-cnt %{INT:[cisco][asa][hit_count]:int} (?:first hit|%{INT:[cisco][asa][interval]:int}-second interval)
18 | CISCO_SRC_IP_USER %{NOTSPACE:[observer][ingress][interface][name]}:%{IP:[source][ip]}(?:\(%{DATA:[source][user][name]}\))?
19 | CISCO_DST_IP_USER %{NOTSPACE:[observer][egress][interface][name]}:%{IP:[destination][ip]}(?:\(%{DATA:[destination][user][name]}\))?
20 | CISCO_SRC_HOST_PORT_USER %{NOTSPACE:[observer][ingress][interface][name]}:(?:(?:%{IP:[source][ip]})|(?:%{HOSTNAME:[source][address]}))(?:/%{INT:[source][port]:int})?(?:\(%{DATA:[source][user][name]}\))?
21 | CISCO_DST_HOST_PORT_USER %{NOTSPACE:[observer][egress][interface][name]}:(?:(?:%{IP:[destination][ip]})|(?:%{HOSTNAME:[destination][address]}))(?:/%{INT:[destination][port]:int})?(?:\(%{DATA:[destination][user][name]}\))?
22 | # ASA-1-104001
23 | CISCOFW104001 \((?:Primary|Secondary)\) Switching to ACTIVE - %{GREEDYDATA:[event][reason]}
24 | # ASA-1-104002
25 | CISCOFW104002 \((?:Primary|Secondary)\) Switching to STANDBY - %{GREEDYDATA:[event][reason]}
26 | # ASA-1-104003
27 | CISCOFW104003 \((?:Primary|Secondary)\) Switching to FAILED\.
28 | # ASA-1-104004
29 | CISCOFW104004 \((?:Primary|Secondary)\) Switching to OK\.
30 | # ASA-1-105003
31 | CISCOFW105003 \((?:Primary|Secondary)\) Monitoring on [Ii]nterface %{NOTSPACE:[network][interface][name]} waiting
32 | # ASA-1-105004
33 | CISCOFW105004 \((?:Primary|Secondary)\) Monitoring on [Ii]nterface %{NOTSPACE:[network][interface][name]} normal
34 | # ASA-1-105005
35 | CISCOFW105005 \((?:Primary|Secondary)\) Lost Failover communications with mate on [Ii]nterface %{NOTSPACE:[network][interface][name]}
36 | # ASA-1-105008
37 | CISCOFW105008 \((?:Primary|Secondary)\) Testing [Ii]nterface %{NOTSPACE:[network][interface][name]}
38 | # ASA-1-105009
39 | CISCOFW105009 \((?:Primary|Secondary)\) Testing on [Ii]nterface %{NOTSPACE:[network][interface][name]} (?:Passed|Failed)
40 | # ASA-2-106001
41 | CISCOFW106001 %{CISCO_DIRECTION:[cisco][asa][network][direction]} %{WORD:[cisco][asa][network][transport]} connection %{CISCO_ACTION:[cisco][asa][outcome]} from %{IP:[source][ip]}/%{INT:[source][port]:int} to %{IP:[destination][ip]}/%{INT:[destination][port]:int} flags %{DATA:[cisco][asa][tcp_flags]} on interface %{NOTSPACE:[observer][egress][interface][name]}
42 | # ASA-2-106006, ASA-2-106007, ASA-2-106010
43 | CISCOFW106006_106007_106010 %{CISCO_ACTION:[cisco][asa][outcome]} %{CISCO_DIRECTION:[cisco][asa][network][direction]} %{WORD:[cisco][asa][network][transport]} (?:from|src) %{IP:[source][ip]}/%{INT:[source][port]:int}(?:\(%{DATA:[source][user][name]}\))? (?:to|dst) %{IP:[destination][ip]}/%{INT:[destination][port]:int}(?:\(%{DATA:[destination][user][name]}\))? (?:(?:on interface %{NOTSPACE:[observer][egress][interface][name]})|(?:due to %{CISCO_REASON:[event][reason]}))
44 | # ASA-3-106014
45 | CISCOFW106014 %{CISCO_ACTION:[cisco][asa][outcome]} %{CISCO_DIRECTION:[cisco][asa][network][direction]} %{WORD:[cisco][asa][network][transport]} src %{CISCO_SRC_IP_USER} dst %{CISCO_DST_IP_USER}\s?\(type %{INT:[cisco][asa][icmp_type]:int}, code %{INT:[cisco][asa][icmp_code]:int}\)
46 | # ASA-6-106015
47 | CISCOFW106015 %{CISCO_ACTION:[cisco][asa][outcome]} %{WORD:[cisco][asa][network][transport]} \(%{DATA:[cisco][asa][rule_name]}\) from %{IP:[source][ip]}/%{INT:[source][port]:int} to %{IP:[destination][ip]}/%{INT:[destination][port]:int} flags %{DATA:[cisco][asa][tcp_flags]} on interface %{NOTSPACE:[observer][egress][interface][name]}
48 | # ASA-1-106021
49 | CISCOFW106021 %{CISCO_ACTION:[cisco][asa][outcome]} %{WORD:[cisco][asa][network][transport]} reverse path check from %{IP:[source][ip]} to %{IP:[destination][ip]} on interface %{NOTSPACE:[observer][egress][interface][name]}
50 | # ASA-4-106023
51 | CISCOFW106023 %{CISCO_ACTION:[cisco][asa][outcome]}(?: protocol)? %{WORD:[cisco][asa][network][transport]} src %{CISCO_SRC_HOST_PORT_USER} dst %{CISCO_DST_HOST_PORT_USER}( \(type %{INT:[cisco][asa][icmp_type]:int}, code %{INT:[cisco][asa][icmp_code]:int}\))? by access-group "?%{DATA:[cisco][asa][rule_name]}"? \[%{DATA:[@metadata][cisco][asa][hashcode1]}, %{DATA:[@metadata][cisco][asa][hashcode2]}\]
52 | # ASA-4-106100, ASA-4-106102, ASA-4-106103
53 | CISCOFW106100_2_3 access-list %{NOTSPACE:[cisco][asa][rule_name]} %{CISCO_ACTION:[cisco][asa][outcome]} %{WORD:[cisco][asa][network][transport]} for user '%{DATA:[user][name]}' %{DATA:[observer][ingress][interface][name]}/%{IP:[source][ip]}\(%{INT:[source][port]:int}\) -> %{DATA:[observer][egress][interface][name]}/%{IP:[destination][ip]}\(%{INT:[destination][port]:int}\) %{CISCO_HITCOUNT_INTERVAL} \[%{DATA:[@metadata][cisco][asa][hashcode1]}, %{DATA:[@metadata][cisco][asa][hashcode2]}\]
54 | # ASA-5-106100
55 | CISCOFW106100 access-list %{NOTSPACE:[cisco][asa][rule_name]} %{CISCO_ACTION:[cisco][asa][outcome]} %{WORD:[cisco][asa][network][transport]} %{DATA:[observer][ingress][interface][name]}/%{IP:[source][ip]}\(%{INT:[source][port]:int}\)(?:\(%{DATA:[source][user][name]}\))? -> %{DATA:[observer][egress][interface][name]}/%{IP:[destination][ip]}\(%{INT:[destination][port]:int}\)(?:\(%{DATA:[source][user][name]}\))? hit-cnt %{INT:[cisco][asa][hit_count]:int} %{CISCO_INTERVAL} \[%{DATA:[@metadata][cisco][asa][hashcode1]}, %{DATA:[@metadata][cisco][asa][hashcode2]}\]
56 | # ASA-5-304001
57 | CISCOFW304001 %{IP:[source][ip]}(?:\(%{DATA:[source][user][name]}\))? Accessed URL %{IP:[destination][ip]}:%{GREEDYDATA:[url][original]}
58 | # ASA-6-110002
59 | CISCOFW110002 %{CISCO_REASON:[event][reason]} for %{WORD:[cisco][asa][network][transport]} from %{DATA:[observer][ingress][interface][name]}:%{IP:[source][ip]}/%{INT:[source][port]:int} to %{IP:[destination][ip]}/%{INT:[destination][port]:int}
60 | # ASA-6-302010
61 | CISCOFW302010 %{INT:[cisco][asa][connections][in_use]:int} in use, %{INT:[cisco][asa][connections][most_used]:int} most used
62 | # ASA-6-302013, ASA-6-302014, ASA-6-302015, ASA-6-302016
63 | CISCOFW302013_302014_302015_302016 %{CISCO_ACTION:[cisco][asa][outcome]}(?: %{CISCO_DIRECTION:[cisco][asa][network][direction]})? %{WORD:[cisco][asa][network][transport]} connection %{INT:[cisco][asa][connection_id]} for %{NOTSPACE:[observer][ingress][interface][name]}:%{IP:[source][ip]}/%{INT:[source][port]:int}(?: \(%{IP:[source][nat][ip]}/%{INT:[source][nat][port]:int}\))?(?:\(%{DATA:[source][user][name]}\))? to %{NOTSPACE:[observer][egress][interface][name]}:%{IP:[destination][ip]}/%{INT:[destination][port]:int}( \(%{IP:[destination][nat][ip]}/%{INT:[destination][nat][port]:int}\))?(?:\(%{DATA:[destination][user][name]}\))?( duration %{TIME:[cisco][asa][duration]} bytes %{INT:[network][bytes]:int})?(?: %{CISCO_REASON:[event][reason]})?(?: \(%{DATA:[user][name]}\))?
64 | # :long - %{INT:[network][bytes]:int}
65 | # ASA-6-302020, ASA-6-302021
66 | CISCOFW302020_302021 %{CISCO_ACTION:[cisco][asa][outcome]}(?: %{CISCO_DIRECTION:[cisco][asa][network][direction]})? %{WORD:[cisco][asa][network][transport]} connection for faddr %{IP:[destination][ip]}/%{INT:[cisco][asa][icmp_seq]:int}(?:\(%{DATA:[destination][user][name]}\))? gaddr %{IP:[source][nat][ip]}/%{INT:[cisco][asa][icmp_type]:int} laddr %{IP:[source][ip]}/%{INT}(?: \(%{DATA:[source][user][name]}\))?
67 | # ASA-6-305011
68 | CISCOFW305011 %{CISCO_ACTION:[cisco][asa][outcome]} %{CISCO_XLATE_TYPE} %{WORD:[cisco][asa][network][transport]} translation from %{DATA:[observer][ingress][interface][name]}:%{IP:[source][ip]}(/%{INT:[source][port]:int})?(?:\(%{DATA:[source][user][name]}\))? to %{DATA:[observer][egress][interface][name]}:%{IP:[destination][ip]}/%{INT:[destination][port]:int}
69 | # ASA-3-313001, ASA-3-313004, ASA-3-313008
70 | CISCOFW313001_313004_313008 %{CISCO_ACTION:[cisco][asa][outcome]} %{WORD:[cisco][asa][network][transport]} type=%{INT:[cisco][asa][icmp_type]:int}, code=%{INT:[cisco][asa][icmp_code]:int} from %{IP:[source][ip]} on interface %{NOTSPACE:[observer][egress][interface][name]}(?: to %{IP:[destination][ip]})?
71 | # ASA-4-313005
72 | CISCOFW313005 %{CISCO_REASON:[event][reason]} for %{WORD:[cisco][asa][network][transport]} error message: %{WORD} src %{CISCO_SRC_IP_USER} dst %{CISCO_DST_IP_USER} \(type %{INT:[cisco][asa][icmp_type]:int}, code %{INT:[cisco][asa][icmp_code]:int}\) on %{NOTSPACE} interface\.\s+Original IP payload: %{WORD:[cisco][asa][original_ip_payload][network][transport]} src %{IP:[cisco][asa][original_ip_payload][source][ip]}/%{INT:[cisco][asa][original_ip_payload][source][port]:int}(?:\(%{DATA:[cisco][asa][original_ip_payload][source][user][name]}\))? dst %{IP:[cisco][asa][original_ip_payload][destination][ip]}/%{INT:[cisco][asa][original_ip_payload][destination][port]:int}(?:\(%{DATA:[cisco][asa][original_ip_payload][destination][user][name]}\))?
73 | # ASA-5-321001
74 | CISCOFW321001 Resource '%{DATA:[cisco][asa][resource][name]}' limit of %{POSINT:[cisco][asa][resource][limit]:int} reached for system
75 | # ASA-4-402117
76 | CISCOFW402117 %{WORD:[cisco][asa][network][type]}: Received a non-IPSec packet \(protocol=\s?%{WORD:[cisco][asa][network][transport]}\) from %{IP:[source][ip]} to %{IP:[destination][ip]}\.?
77 | # ASA-4-402119
78 | CISCOFW402119 %{WORD:[cisco][asa][network][type]}: Received an %{WORD:[cisco][asa][ipsec][protocol]} packet \(SPI=\s?%{DATA:[cisco][asa][ipsec][spi]}, sequence number=\s?%{DATA:[cisco][asa][ipsec][seq_num]}\) from %{IP:[source][ip]} \(user=\s?%{DATA:[source][user][name]}\) to %{IP:[destination][ip]} that failed anti-replay checking\.?
79 | # ASA-4-419001
80 | CISCOFW419001 %{CISCO_ACTION:[cisco][asa][outcome]} %{WORD:[cisco][asa][network][transport]} packet from %{NOTSPACE:[observer][ingress][interface][name]}:%{IP:[source][ip]}/%{INT:[source][port]:int} to %{NOTSPACE:[observer][egress][interface][name]}:%{IP:[destination][ip]}/%{INT:[destination][port]:int}, reason: %{GREEDYDATA:[event][reason]}
81 | # ASA-4-419002
82 | CISCOFW419002 %{CISCO_REASON:[event][reason]} from %{DATA:[observer][ingress][interface][name]}:%{IP:[source][ip]}/%{INT:[source][port]:int} to %{DATA:[observer][egress][interface][name]}:%{IP:[destination][ip]}/%{INT:[destination][port]:int} with different initial sequence number
83 | # ASA-4-500004
84 | CISCOFW500004 %{CISCO_REASON:[event][reason]} for protocol=%{WORD:[cisco][asa][network][transport]}, from %{IP:[source][ip]}/%{INT:[source][port]:int} to %{IP:[destination][ip]}/%{INT:[destination][port]:int}
85 | # ASA-6-602303, ASA-6-602304
86 | CISCOFW602303_602304 %{WORD:[cisco][asa][network][type]}: An %{CISCO_DIRECTION:[cisco][asa][network][direction]} %{DATA:[cisco][asa][ipsec][tunnel_type]} SA \(SPI=\s?%{DATA:[cisco][asa][ipsec][spi]}\) between %{IP:[source][ip]} and %{IP:[destination][ip]} \(user=\s?%{DATA:[source][user][name]}\) has been %{CISCO_ACTION:[cisco][asa][outcome]}
87 | # ASA-7-710001, ASA-7-710002, ASA-7-710003, ASA-7-710005, ASA-7-710006
88 | CISCOFW710001_710002_710003_710005_710006 %{WORD:[cisco][asa][network][transport]} (?:request|access) %{CISCO_ACTION:[cisco][asa][outcome]} from %{IP:[source][ip]}/%{INT:[source][port]:int} to %{DATA:[observer][egress][interface][name]}:%{IP:[destination][ip]}/%{INT:[destination][port]:int}
89 | # ASA-6-713172
90 | CISCOFW713172 Group = %{DATA:[cisco][asa][source][group]}, IP = %{IP:[source][ip]}, Automatic NAT Detection Status:\s+Remote end\s*%{DATA:[@metadata][cisco][asa][remote_nat]}\s*behind a NAT device\s+This\s+end\s*%{DATA:[@metadata][cisco][asa][local_nat]}\s*behind a NAT device
91 | # ASA-4-733100
92 | CISCOFW733100 \[\s*%{DATA:[cisco][asa][burst][object]}\s*\] drop %{DATA:[cisco][asa][burst][id]} exceeded. Current burst rate is %{INT:[cisco][asa][burst][current_rate]:int} per second, max configured rate is %{INT:[cisco][asa][burst][configured_rate]:int}; Current average rate is %{INT:[cisco][asa][burst][avg_rate]:int} per second, max configured rate is %{INT:[cisco][asa][burst][configured_avg_rate]:int}; Cumulative total count is %{INT:[cisco][asa][burst][cumulative_count]:int}
93 | #== End Cisco ASA ==
94 |
95 |
96 | IPTABLES_TCP_FLAGS (CWR |ECE |URG |ACK |PSH |RST |SYN |FIN )*
97 | IPTABLES_TCP_PART (?:SEQ=%{INT:[iptables][tcp][seq]:int}\s+)?(?:ACK=%{INT:[iptables][tcp][ack]:int}\s+)?WINDOW=%{INT:[iptables][tcp][window]:int}\s+RES=0x%{BASE16NUM:[iptables][tcp_reserved_bits]}\s+%{IPTABLES_TCP_FLAGS:[iptables][tcp][flags]}
98 |
99 | IPTABLES4_FRAG (?:(?<= )(?:CE|DF|MF))*
100 | IPTABLES4_PART SRC=%{IPV4:[source][ip]}\s+DST=%{IPV4:[destination][ip]}\s+LEN=(?:%{INT:[iptables][length]:int})?\s+TOS=(?:0|0x%{BASE16NUM:[iptables][tos]})?\s+PREC=(?:0x%{BASE16NUM:[iptables][precedence_bits]})?\s+TTL=(?:%{INT:[iptables][ttl]:int})?\s+ID=(?:%{INT:[iptables][id]})?\s+(?:%{IPTABLES4_FRAG:[iptables][fragment_flags]})?(?:\s+FRAG: %{INT:[iptables][fragment_offset]:int})?
101 | IPTABLES6_PART SRC=%{IPV6:[source][ip]}\s+DST=%{IPV6:[destination][ip]}\s+LEN=(?:%{INT:[iptables][length]:int})?\s+TC=(?:0|0x%{BASE16NUM:[iptables][tos]})?\s+HOPLIMIT=(?:%{INT:[iptables][ttl]:int})?\s+FLOWLBL=(?:%{INT:[iptables][flow_label]})?
102 |
103 | IPTABLES IN=(?:%{NOTSPACE:[observer][ingress][interface][name]})?\s+OUT=(?:%{NOTSPACE:[observer][egress][interface][name]})?\s+(?:MAC=(?:%{COMMONMAC:[destination][mac]})?(?::%{COMMONMAC:[source][mac]})?(?::[A-Fa-f0-9]{2}:[A-Fa-f0-9]{2})?\s+)?(:?%{IPTABLES4_PART}|%{IPTABLES6_PART}).*?PROTO=(?:%{WORD:[network][transport]})?\s+SPT=(?:%{INT:[source][port]:int})?\s+DPT=(?:%{INT:[destination][port]:int})?\s+(?:%{IPTABLES_TCP_PART})?
104 |
105 | # Shorewall firewall logs
106 | SHOREWALL (?:%{SYSLOGTIMESTAMP:timestamp}) (?:%{WORD:[observer][hostname]}) .*Shorewall:(?:%{WORD:[shorewall][firewall][type]})?:(?:%{WORD:[shorewall][firewall][action]})?.*%{IPTABLES}
107 | #== End Shorewall
108 | #== SuSE Firewall 2 ==
109 | SFW2_LOG_PREFIX SFW2\-INext\-%{NOTSPACE:[suse][firewall][action]}
110 | SFW2 ((?:%{SYSLOGTIMESTAMP:timestamp})|(?:%{TIMESTAMP_ISO8601:timestamp}))\s*%{HOSTNAME:[observer][hostname]}.*?%{SFW2_LOG_PREFIX:[suse][firewall][log_prefix]}\s*%{IPTABLES}
111 | #== End SuSE ==
112 |
--------------------------------------------------------------------------------
/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState, useRef } from "react";
2 | import { GrokCollection } from "grok-js";
3 | import { Navbar } from "./components/Navbar";
4 | import { UnControlled as CodeMirrorTextarea } from "react-codemirror2";
5 | import { Book, Copy, Share2, Trash2, Check, PlusSquare, DownloadCloud, ExternalLink } from "react-feather";
6 | import CodeMirror from "codemirror";
7 | import "codemirror/addon/mode/simple";
8 | import "codemirror/addon/hint/show-hint";
9 | import "codemirror/mode/javascript/javascript";
10 | import "codemirror/addon/selection/mark-selection";
11 | import "codemirror/addon/scroll/simplescrollbars";
12 | import grokMode from "./codemirror/grok";
13 | import { LoadModal } from "./components/LoadModal";
14 | import { ShareModal } from "./components/ShareModal";
15 | import { Ad } from "./components/Ad";
16 | import { CustomPatternModal } from "./components/CustomPatternModal";
17 | import Select from "react-select";
18 | import useLocalStorage from "./hooks/useLocalStorage";
19 | import { MorePatternsModal } from "./components/MorePatternsModal";
20 |
21 | function App() {
22 | CodeMirror.defineSimpleMode("grokMode", grokMode);
23 |
24 | const urlSearchParams = new URLSearchParams(window.location.search);
25 | const qsParams = Object.fromEntries(urlSearchParams.entries());
26 |
27 | const [groks] = useState(new GrokCollection());
28 | let [pattern, setPattern] = useLocalStorage("gd-pattern", "");
29 | let [sample, setSample] = useLocalStorage(
30 | "gd-sample",
31 | "Your sample logs go here\nStart typing a pattern above for suggestions, e.g. %{WORD:word}\nNamed capture groups work too, e.g. (?pattern)"
32 | );
33 | let [result, setResult] = useState("");
34 | let [samplesEditor, setSamplesEditor] = useState();
35 | let [patterns, setPatterns] = useState([]);
36 | let [customPatterns, setCustomPatterns] = useLocalStorage("gd-custom", []);
37 | let [showModal, setShowModal] = useState(null);
38 | let [matchCount, setMatchCount] = useState(0);
39 | let [sampleCount, setSampleCount] = useState(0);
40 |
41 | const defaultCollections = [
42 | { value: "custom", label: "Custom", active: true },
43 | { value: "aws", label: "AWS", active: false },
44 | { value: "bacula", label: "Bacula", active: false },
45 | { value: "bind", label: "BIND", active: false },
46 | { value: "bro", label: "Bro", active: false },
47 | { value: "exim", label: "Exim", active: false },
48 | { value: "firewalls", label: "Firewalls", active: false },
49 | { value: "grok-patterns", label: "Grok Patterns", active: true },
50 | { value: "haproxy", label: "HAProxy", active: false },
51 | { value: "httpd", label: "Httpd", active: false },
52 | { value: "java", label: "Java", active: false },
53 | { value: "junos", label: "Junos", active: false },
54 | { value: "linux-syslog", label: "Syslog", active: false },
55 | { value: "maven", label: "Maven", active: false },
56 | { value: "mcollective", label: "MCollective", active: false },
57 | { value: "mongodb", label: "MongoDB", active: false },
58 | { value: "nagios", label: "Nagios", active: false },
59 | { value: "postfix", label: "Postfix", active: false },
60 | { value: "postgresql", label: "PostgreSQL", active: false },
61 | { value: "rails", label: "Rails", active: false },
62 | { value: "redis", label: "Redis", active: false },
63 | { value: "ruby", label: "Ruby", active: false },
64 | { value: "squid", label: "Squid", active: false },
65 | { value: "zeek", label: "Zeek", active: false },
66 | ];
67 |
68 | let [collections, setCollections] = useLocalStorage("gd-collections", defaultCollections);
69 |
70 | const firstUpdate = useRef(true);
71 |
72 | const loadExternalPatterns = async () => {
73 | await Promise.all(
74 | collections.filter((c) => c.active && c.value !== "custom").map((c) => loadCollection(c.value, c.label, c.url))
75 | );
76 | };
77 |
78 | const loadCustomPatterns = async () => {
79 | customPatterns.map((p) => {
80 | groks.createPattern(p.pattern, p.id);
81 | });
82 | };
83 |
84 | useEffect(() => {
85 | setPatterns((patterns) => [
86 | ...patterns,
87 | ...customPatterns.map((p) => {
88 | return { id: p.id, collection: "custom" };
89 | }),
90 | ]);
91 | }, [customPatterns]);
92 |
93 | const onLoad = async () => {
94 | // load query string parameters (if there are any)
95 | if (qsParams.pattern) setPattern(qsParams.pattern);
96 | if (qsParams.sample) setSample(qsParams.sample);
97 | await loadExternalPatterns();
98 | await loadCustomPatterns();
99 |
100 | // add any collections in default that user does not have in localstorage store
101 | const newCollections = defaultCollections.filter((d) => {
102 | return !collections.map((c) => c.value).includes(d.value);
103 | });
104 | if (newCollections.length) {
105 | setCollections((collections) => [...collections, ...newCollections]);
106 | }
107 | };
108 |
109 | const loadCollection = async (value, label, url) => {
110 | if (patterns.find((p) => p.collection === value)) return;
111 | label = label || value;
112 | url = url || "/patterns/" + value;
113 | try {
114 | const newPatterns = await groks.load(url).then((ids) => {
115 | return ids.map((id) => {
116 | if (patterns.includes({ id, collection: value })) return;
117 | return { id, collection: value };
118 | });
119 | });
120 | setPatterns((patterns) => [...patterns, ...newPatterns.flat()]);
121 | const updatedCollection = [...collections].map((c) => {
122 | if (c.value == value) {
123 | return { ...c, active: true };
124 | } else {
125 | return c;
126 | }
127 | });
128 | setCollections(updatedCollection);
129 | } catch (err) {
130 | console.log(err);
131 | }
132 | };
133 |
134 | const parseSample = async (lineNumber) => {
135 | try {
136 | let p = groks.createPattern(pattern);
137 | let sampleLine = samplesEditor.getLine(lineNumber);
138 | let result = await p.parse(sampleLine);
139 | if (!result) return null;
140 | let matches = p.regexp.searchSync(sampleLine).filter((m) => m.length > 0);
141 | matches.forEach((m, i) => {
142 | let bgColor = i === 0 ? "rgb(230, 180, 50, 0.3)" : "rgb(127, 191, 63, 0.4)";
143 | samplesEditor.markText(
144 | { line: lineNumber, ch: m.start },
145 | { line: lineNumber, ch: m.end },
146 | { css: "background-color: " + bgColor + " !important" }
147 | );
148 | });
149 | let data = {};
150 | Object.keys(result).map((key, i) => {
151 | data[key] = +result[key] === 0 ? 0 : +result[key] || result[key];
152 | });
153 | return data;
154 | } catch (error) {
155 | console.error(error);
156 | }
157 | };
158 |
159 | const handleParse = async () => {
160 | try {
161 | let output = [];
162 | const lines = samplesEditor.lineCount() - 1;
163 | for (let i = 0; i <= lines; i++) {
164 | samplesEditor.markText(
165 | { line: i, ch: 0 },
166 | { line: i, ch: Infinity },
167 | { css: "background-color: transparent !important" }
168 | );
169 | let data = await parseSample(i);
170 | output.push(data);
171 | }
172 | setMatchCount(output.reduce((acc, val) => (acc += +(val !== null)), 0));
173 | setSampleCount(output.length);
174 | setResult(JSON.stringify(output, null, 2));
175 | } catch (error) {
176 | console.error(error);
177 | }
178 | };
179 |
180 | useEffect(() => {
181 | onLoad();
182 | }, []);
183 |
184 | useEffect(() => {
185 | if (firstUpdate.current) {
186 | firstUpdate.current = false;
187 | return;
188 | }
189 | let timeout = setTimeout(() => handleParse(), 250);
190 | return () => clearTimeout(timeout);
191 | }, [pattern, sample, patterns]);
192 |
193 | const handleChangePattern = (editor, data, value) => {
194 | setPattern(value);
195 | };
196 |
197 | const handleSelectAction = async (newValue, actionMeta) => {
198 | const { action, option } = actionMeta;
199 | let newCollections = [...collections];
200 | switch (action) {
201 | case "select-option":
202 | if (patterns.find((p) => p.collection === option.value)) {
203 | newCollections = newCollections.map((c) => {
204 | if (c.value === option.value) {
205 | return { ...c, active: true };
206 | } else {
207 | return c;
208 | }
209 | });
210 | setCollections(newCollections);
211 | } else {
212 | loadCollection(option.value, option.label, option.url);
213 | }
214 | break;
215 | case "remove-value":
216 | newCollections = newCollections.map((c) =>
217 | newValue.map((nv) => nv.value).includes(c.value) ? { ...c, active: true } : { ...c, active: false }
218 | );
219 | setCollections(newCollections);
220 | break;
221 | case "clear":
222 | newCollections = newCollections.map((c) => {
223 | return { ...c, active: false };
224 | });
225 | setCollections(newCollections);
226 | break;
227 | default:
228 | break;
229 | }
230 | };
231 |
232 | const copyToClipboard = (text) => {
233 | navigator.clipboard.writeText(text);
234 | };
235 |
236 | return (
237 |
238 |
239 |
240 |
241 |
242 |
243 |
265 |
266 |
274 |
275 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
Grok Pattern
287 |
288 | copyToClipboard(pattern)} />
289 |
290 |
291 |
setShowModal("CUSTOM_PATTERN")} />
292 |
293 |
294 | setShowModal("LOAD")} />
295 |
296 |
297 | setShowModal("SHARE")} />
298 |
299 |
300 |
{
313 | let cursorPos = editor.getDoc().getCursor();
314 | let lastTokenRegex = /%{([^:}]*)$/g;
315 | let keyword = lastTokenRegex.exec(pattern.substr(0, cursorPos.ch));
316 | if (keyword !== null) {
317 | const activeCollections = collections.filter((c) => c.active).map((c) => c.value);
318 | return {
319 | from: { ...cursorPos, ch: cursorPos.ch - keyword[1].length },
320 | to: cursorPos,
321 | list: patterns
322 | .filter((p) => activeCollections.includes(p.collection))
323 | .filter((p) => RegExp(keyword[1], "i").test(p.id))
324 | .map((p) => p.id),
325 | };
326 | }
327 | },
328 | },
329 | }}
330 | onInputRead={(editor, change) => {
331 | CodeMirror.showHint(editor);
332 | }}
333 | value={pattern}
334 | onChange={handleChangePattern}
335 | autoCursor={false}
336 | />
337 |
338 |
339 |
340 |
Samples
341 |
342 | copyToClipboard(sample)} />
343 |
344 |
345 | setSample()} />
346 |
347 |
348 |
setSample(value)}
360 | autoCursor={false}
361 | editorDidMount={(editor) => {
362 | setSamplesEditor(editor);
363 | }}
364 | />
365 |
366 |
367 |
368 |
369 |
370 |
371 |
Output
372 |
373 | copyToClipboard(result)} />
374 |
375 |
376 |
377 | {!sampleCount ? <>> : matchCount === sampleCount ? : <>>}
378 | {matchCount}
379 | {"/"}
380 | {sampleCount}
381 |
382 |
383 |
394 |
395 |
396 | {
397 | {
398 | LOAD: (
399 |
405 | ),
406 | SHARE:
,
407 | CUSTOM_PATTERN: (
408 |
417 | ),
418 | MORE_PATTERNS: (
419 |
427 | ),
428 | }[showModal]
429 | }
430 |
431 |
432 | );
433 | }
434 |
435 | export default App;
436 |
--------------------------------------------------------------------------------