Skip to content

Commit

Permalink
feat: add metric charts
Browse files Browse the repository at this point in the history
  • Loading branch information
jacovinus committed Sep 20, 2024
1 parent 56c3436 commit bb3cadc
Show file tree
Hide file tree
Showing 14 changed files with 460 additions and 47 deletions.
1 change: 1 addition & 0 deletions packages/main/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"dayjs": "^1.11.12",
"deep-freeze": "^0.0.1",
"dnd-core": "^16.0.1",
"echarts": "^5.5.1",
"fuzzy": "^0.1.3",
"immutability-helper": "^3.1.1",
"isomorphic-dompurify": "^1.13.0",
Expand Down
3 changes: 3 additions & 0 deletions packages/main/plugins/WebVitals/helper/webVitals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ const format_logs_queue = async (queue: QueueItem[]) => {
level: "info",
job: "webVitals",
name: metric.name,
metricName: metric.name,
metricLabel: "page",
description:
MetricDescription[
metric.name as keyof typeof MetricDescription
Expand All @@ -108,6 +110,7 @@ const format_logs_queue = async (queue: QueueItem[]) => {
delta: metric.delta?.toString() || "N/A",
traceId: traceId,
page: page,
hasMetrics:true,
},
values: [[String(Date.now() * 1000000), logString]],
};
Expand Down
153 changes: 153 additions & 0 deletions packages/main/plugins/WebVitals/performanceAxios.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
import axios, { AxiosResponse } from "axios";

import { LOKI_WRITE, METRICS_WRITE, TEMPO_WRITE } from "./helper/webVitals";
import { v4 as uuidv4 } from "uuid";

interface PerformanceEntry {
name: string;
startTime: number;
duration: number;
type?:string;
level?:string;
method: string;
url: string;
status: number;
traceId: string;
}

const performanceQueue: Set<PerformanceEntry> = new Set();

export async function flushPerformanceQueue() {
if (performanceQueue.size === 0) return;

const entries = Array.from(performanceQueue);

// Format metrics
const metricsData = entries
.map(
(entry) =>
`http_request,method=${entry.method},type=${entry.type},status=${entry.status} duration=${Math.round(entry.duration)} ${Date.now() * 1000000}`,
)
.join("\n");

console.log(metricsData)

// Format logs
const logsData = JSON.stringify({
streams: entries.map((entry) => ({
stream: {
level: entry.level ?? "info",
job: "httpRequest",
metricName:"http_request",
metricLabel:"type",
type: entry.type,
method: entry.method,
url: entry.url,
status: entry.status.toString(),
traceId: entry.traceId,
},
values: [
[
String(Date.now() * 1000000),
`HTTP ${entry.method} ${entry.url} completed in ${entry.duration}ms with status ${entry.status}`,
],
],
})),
});

// Format traces
const tracesData = entries.map((entry) => ({
id: uuidv4().replace(/-/g, ""),
traceId: entry.traceId,
name: `HTTP ${entry.type}`,

timestamp:Math.floor(Date.now() * 1000), // microseconds
duration: Math.floor(entry.duration * 1000) , // microseconds
tags: {
"http.method": entry.method,
"http.url": entry.url,
"http.status_code": entry.status.toString(),
},
localEndpoint: {
serviceName: "httpClient",
},
}));

console.log(tracesData)

try {
await Promise.all([
fetch(METRICS_WRITE, {
method: "POST",
headers: { "Content-Type": "text/plain" },
body: metricsData,
}),
fetch(LOKI_WRITE, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: logsData,
}),
fetch(TEMPO_WRITE, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(tracesData),
}),
]);
} catch (error) {
console.error("Error flushing performance queue:", error);

}

performanceQueue.clear();
}



export function performanceAxios(
config: any,
): Promise<AxiosResponse> {
const startTime = performance.now();
const traceId = uuidv4().replace(/-/g, "");
console.log(config)
return axios(config)
.then((response) => {
const endTime = performance.now();
const duration = endTime - startTime;

const entry: PerformanceEntry = {
name: `${config.method} ${config.url}`,
type:config.type,
level:"info",
startTime,
duration,
method: config.method?.toUpperCase() || "GET",
url: config.url || "",
status: response.status,
traceId,
};

performanceQueue.add(entry);

return response;
})
.catch((error) => {
const endTime = performance.now();
const duration = endTime - startTime;

const entry: PerformanceEntry = {
name: `${config.method} ${config.url} (failed)`,
startTime,
duration,
type: config.type,
level:'error',
method: config.method?.toUpperCase() || "GET",
url: config.url || "",
status: error.response?.status || 0,
traceId,
};

performanceQueue.add(entry);

throw error;
});
}
7 changes: 3 additions & 4 deletions packages/main/sections/Queries/QueryItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
getStoredQueries,
setStoredQuery,
setLocalTabsState,
getLocalTabsState
getLocalTabsState,
} from "./helpers";
import { useIdRefs } from "./hooks";

Expand Down Expand Up @@ -46,6 +46,8 @@ function TabPanel(props: TabPanelProps) {

const QueryItem = (props: any) => {
const { name, data } = props;

console.log(data)
const { id } = data;
const [launchQuery, setLaunchQuery] = useState("");
const dispatch: any = useDispatch();
Expand All @@ -64,7 +66,6 @@ const QueryItem = (props: any) => {

const deleteStoredQuery = (): void => {
const prevStored = getStoredQueries();

if (prevStored?.length > 0) {
const filtered = filterLocal(prevStored, id);
setStoredQuery(filtered);
Expand All @@ -73,9 +74,7 @@ const QueryItem = (props: any) => {

const onDeleteQuery = (): void => {
const filtered = filterPanel(panelSelected, id);

const viewFiltered = filterPanel(dataView, id);

const prevStoredQuery = getStoredQueries();

if (prevStoredQuery?.length > 0) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@

import { RowLogContent, RowTimestamp } from "./styled";
import { ILogRowProps } from "./types";

/**
* Returns a Log Row with the row timestamp and text
* @param param0
* @returns
* @param param0
* @returns
*/
export function LogRow({
text,
dateFormated,
isMobile,
isSplit,
isShowTs,
onRowClick,
}: ILogRowProps) {
const showTimestamp = () => isShowTs && !isMobile && !isSplit;
const dateFormatted = () => (isMobile || isSplit) && isShowTs;

return (
<div className="log-ts-row">
<div className="log-ts-row" onClick={onRowClick}>
{showTimestamp() && <RowTimestamp>{dateFormated}</RowTimestamp>}
<RowLogContent>
{dateFormatted() && <p>{dateFormated}</p>}
<p>{text}</p>
</RowLogContent>
</div>
);
}
}
20 changes: 10 additions & 10 deletions packages/main/src/components/DataViews/components/Logs/Row.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,17 @@ export function Row(props: IRowProps) {
dataSourceData,
};

const rowProps = {
rowColor,
onClick: () => {
toggleItemActive(index);
},
};

return (
<LogRowStyled {...rowProps}>
<LogRow {...logRowProps} isShowTs={actQuery.isShowTs} />
<ValueTagsCont {...valueTagsProps} />
<LogRowStyled rowColor={rowColor}>
<LogRow
onRowClick={() => toggleItemActive(index)}
{...logRowProps}
isShowTs={actQuery.isShowTs}
/>
<ValueTagsCont
onValueTagsClick={() => toggleItemActive(index)}
{...valueTagsProps}
/>
</LogRowStyled>
);
}
28 changes: 18 additions & 10 deletions packages/main/src/components/DataViews/components/Logs/styled.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import styled from "@emotion/styled";
import {css} from '@emotion/css';
import { css } from "@emotion/css";
import { type QrynTheme } from "@ui/theme/types";

export const FlexWrap = css`
display: flex;
flex-wrap: wrap;
margin-top: 3px;
`;


export const LogRowStyled = styled.div`
color: ${({theme}: any) => theme.contrast};
export const LogRowStyled: any = styled.div<{
theme: QrynTheme;
rowColor: any;
}>`
color: ${({ theme }) => theme.contrast};
font-size: 12px;
cursor: pointer;
padding-left: 0.5rem;
Expand All @@ -20,29 +23,36 @@ export const LogRowStyled = styled.div`
margin-top: 2px;
font-family: monospace;
&:hover {
background: ${({theme}: any) => theme.activeBg};
background: ${({ theme }: any) => theme.activeBg};
}
p {
display: inline-block;
overflow-wrap: anywhere;
margin-left: 3px;
}
border-left: 4px solid ${({rowColor}: any) => rowColor};
border-left: 4px solid ${({ rowColor }: any) => rowColor};
.log-ts-row {
display: flex;
}
.value-tags-close {
height: 12px;
&:hover {
background: ${({ theme }) => theme.shadow};
border-radius: 3px 3px 0px 0px;
}
}
`;

export const RowLogContent = styled.span`
font-size: 12px;
color: ${({theme}: any) => theme.hardContrast};
color: ${({ theme }: any) => theme.hardContrast};
line-height: 1.5;
`;

export const RowTimestamp = styled.span`
position: relative;
color: ${({theme}: any) => theme.contrast};
color: ${({ theme }: any) => theme.contrast};
margin-right: 0.25rem;
white-space: nowrap;
font-size: 12px;
Expand All @@ -54,5 +64,3 @@ export const RowsCont = styled.div`
overflow-y: auto;
height: calc(100% - 20px);
`;


Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export interface ILogRowProps {
isSplit: boolean;
isMobile: boolean;
isShowTs: boolean;
onRowClick : () => void
}

export interface IRowProps {
Expand Down
Loading

0 comments on commit bb3cadc

Please sign in to comment.