Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Added Minimum Log Filter #29

Merged
merged 1 commit into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 60 additions & 64 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { ThemeProvider } from "@emotion/react";
import { useEffect, useState } from "react";
import { useEffect, useState, useReducer } from "react";
import Log_Menu from "./components/Log_Menu.tsx";
import { theme } from "./theme";
import BoxBasic from "./components/Box";
import {PayloadInterface,ActionType,QueryString} from "./schema/interfaces.ts";
import { payload } from "./schema/payload.ts";

import Table from '@mui/material/Table';
import TableBody from '@mui/material/TableBody';
Expand All @@ -10,18 +13,59 @@ import TableContainer from '@mui/material/TableContainer';
import TableRow from '@mui/material/TableRow';
import Paper from '@mui/material/Paper';
import { TableHead } from "@mui/material";
import { log_levels } from "./schema/Log_Levels.ts";

type getMessageReturn = [string[],string[],string[],string[],number[],string[]]
const apiURL = "/api/views/search/sync";
const password = "token";
let username: string;
const query: QueryString = {};

const ACTIONS = {
LOGFILTER: "level",
TBThomas56 marked this conversation as resolved.
Show resolved Hide resolved
BEAMLINE: "beamline",
APP: "application",
};


type getMessageReturn = [string[],string[],string[],string[],number[],string[]];

function App() {
// API responses to be shown
const [time, setTime] = useState<string[]>([]);
const [host, setHost] = useState<string[]>([]);
const [debug, setDebug] = useState<string[]>([]);
const [logs, setLogs] = useState<string[]>([]);
const [log_lvl, setLog_lvl] = useState<number[]>([]);
const [app_name,setApp_name] = useState<string[]>([]);
const [logfilter, setLogfilter] = useState<number>(7);
const [logPayload, handlePayload] = useReducer(reducer, payload);

useEffect(() => {
// Log_Menu Props
const handleLogFilterChange = (newLogFilterValue: number) => {
setLogfilter(newLogFilterValue);
handlePayload({type: ACTIONS.LOGFILTER, log_level: newLogFilterValue});
};

function reducer(payload:PayloadInterface,action:ActionType) {
switch (action.type){
case ACTIONS.LOGFILTER:
query.filter = `level: <=${action.log_level}`;
break;
case ACTIONS.BEAMLINE:
query.beamline = `beamline: ${action.query_condition}`;
break;
case ACTIONS.APP:
query.app_name = `application_name: ${action.query_condition}`;
break;
}
const query_arr:string[] = Object.values(query);
payload.queries[0].query.query_string = query_arr.join(" AND ");
const newPayload = {...payload};
return newPayload
}

useEffect(() => {
console.log(logPayload.queries[0].query.query_string);
async function fetchData(
url: string,
username: string,
Expand Down Expand Up @@ -64,46 +108,6 @@ function App() {
}
}

const apiURL = "/api/views/search/sync";
const password = "token";
let username:string;

// Add payload for the request
const payload = {
// id: "661626cbe7b8a27f59bd1175",
parameters: [],
queries: [
{
query: {
type: "elasticsearch",
query_string: "beamline:i15 AND application_name:gda",
},
timerange: {
from: 300,
type: "relative",
},
filters: [],
search_types: [
{
limit: 100,
offset: 0,
sort: [
{
field: "timestamp",
order: "DESC",
},
],
fields: [],
decorators: [],
type: "messages",
filter: null,
filters: [],
},
],
},
],
};

// reads file from folder - add custom API key to this file
(async () => {
try {
Expand All @@ -123,11 +127,14 @@ function App() {
console.error("Error collecting password:", error);
}
})();
}, []);
}, [logPayload]);



return (
<ThemeProvider theme={theme}>
<h1>Athena Logpanel </h1>
<Log_Menu logFilterValue={logfilter} onLogFilterChange={handleLogFilterChange}/>
<BoxBasic>
<TableContainer component={Paper}>
<Table sx={{ minWidth: 650 }} aria-label="simple table">
Expand All @@ -141,16 +148,18 @@ function App() {
</TableRow>
</TableHead>
<TableBody>
{logs.map((log,index) => (
<TableRow sx={{backgroundColor:getColor(log_lvl[index])}}>
{logs.map((log,index) => {
return (
<TableRow sx={{backgroundColor:getColor(log_lvl[index])}} key={index}>
<TableCell><pre>{time[index]}</pre></TableCell>
<TableCell><pre>{debug[index]}</pre></TableCell>
<TableCell><pre>{host[index]}</pre></TableCell>
<TableCell><pre>{app_name[index]}</pre></TableCell>
<TableCell><pre>{log}</pre></TableCell>
{/* sx={{ '&:last-child td, &:last-child th': { border: 0 } }} */}
</TableRow>
))}
</TableRow>
);
})},
</TableBody>
</Table>
</TableContainer>
Expand All @@ -175,15 +184,15 @@ function getMessage(logging: JSON): undefined | getMessageReturn {
const logs = id[keys].messages;
// populate different components of logged data and identifying log level
for (const msg in logs) {
const formattedTimestamp = logs[msg]["message"]["timestamp"].replace(/[TZ]/g, ' ')
const formattedTimestamp = logs[msg]["message"]["timestamp"].replace(/[TZ]/g, ' ');
timestamp.push(
`${formattedTimestamp}`
);
host.push(logs[msg]["message"]["source"])
host.push(logs[msg]["message"]["source"]);
app_name.push(logs[msg]["message"]["application_name"]);
const level = logs[msg]["message"]["level"];
const log_message = logs[msg]["message"]["full_message"];
const log_level_str = getLogLevel(level);
const log_level_str = log_levels[level] || "UNKNOWN";
debug.push(log_level_str);
message.push(log_message);
log_level.push(level);
Expand All @@ -196,19 +205,6 @@ function getMessage(logging: JSON): undefined | getMessageReturn {
}
}

function getLogLevel(level_val:number): string {
const log_levels: {[key: number]: string} = {
0:"EMERG",
1:"ALERT",
2:"CRIT",
3:"ERROR",
4:"WARN",
5:"NOTICE",
6:"INFO",
7:"DEBUG",};
const level = log_levels[level_val] || "UNKNOWN";
return level;
}
async function readFile(): Promise<string> {
const filePath = "src/token.txt";
const response = await fetch(filePath) ;
Expand Down
43 changes: 43 additions & 0 deletions src/components/Log_Menu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import * as React from 'react';
import Box from '@mui/material/Box';
import InputLabel from '@mui/material/InputLabel';
import MenuItem from '@mui/material/MenuItem';
import FormControl from '@mui/material/FormControl';
import Select, { SelectChangeEvent } from '@mui/material/Select';
import { log_levels } from '../schema/Log_Levels';

interface Props {
logFilterValue: number;
onLogFilterChange: (newLogFilterValue: number) => void;
}

const BasicSelect: React.FC<Props> = ({ logFilterValue, onLogFilterChange }) => {
const handleChange = (event: SelectChangeEvent) => {
const newLogFilterValue = event.target.value as unknown as number;
onLogFilterChange(newLogFilterValue);
};

return (
<Box sx={{ minWidth: 120 }}>
<FormControl fullWidth>
<InputLabel id="log-filter-id">Minimum Log Filter</InputLabel>
<Select
labelId="log-filter-id"
id="log-filter-label"
value={logFilterValue.toString()}
label="Minimum Log Filter"
onChange={handleChange}
>
{Object.entries(log_levels).map(([level_value, level_name]) => (
<MenuItem key={level_value} value={parseInt(level_value)}>
{level_name}
</MenuItem>
))}

</Select>
</FormControl>
</Box>
);
}

export default BasicSelect;
9 changes: 9 additions & 0 deletions src/schema/Log_Levels.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export const log_levels: {[key: number]: string} = {
0:"EMERG",
1:"ALERT",
2:"CRIT",
3:"ERROR",
4:"WARN",
5:"NOTICE",
6:"INFO",
7:"DEBUG",};
50 changes: 50 additions & 0 deletions src/schema/interfaces.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Payload Type Interfaces
export interface PayloadInterface {
parameters: string[];
queries: Query[];
}

export interface Query {
query: QueryDetails;
timerange: Timerange;
filters: string[];
search_types: SearchType[];
}

export interface QueryDetails {
type: string;
query_string: string;
}

export interface Timerange {
from: number;
type: string;
}

export interface SearchType {
limit: number;
offset: number;
sort: Sort[];
fields: string[];
decorators: string[];
type: string;
filter: string | null;
filters: string[];
}

export interface Sort {
field: string;
order: string;
}

export interface ActionType {
type: string;
log_level?: number | 7;
query_condition?: string | "";
}

export interface QueryString {
app_name?: string | "*";
beamline?: string | "*";
filter?: string | "*";
}
34 changes: 34 additions & 0 deletions src/schema/payload.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { PayloadInterface } from "./interfaces";
export const payload: PayloadInterface = {
parameters: [],
queries: [
{
query: {
type: "elasticsearch",
query_string: "",
},
timerange: {
from: 300,
type: "relative",
},
filters: [],
search_types: [
{
limit: 100,
offset: 0,
sort: [
{
field: "timestamp",
order: "DESC",
},
],
fields: [],
decorators: [],
type: "messages",
filter: null,
filters: [],
},
],
},
],
};
Loading