Skip to content

Commit 35595f6

Browse files
committed
ForcePanel: Multiple Filenames searchable, avoid Filename Filters added
1 parent 8d12b15 commit 35595f6

File tree

3 files changed

+122
-99
lines changed

3 files changed

+122
-99
lines changed

Live-Tracing/grafana-plugins/force-graph-plugin/src/ForcePanel.tsx

Lines changed: 105 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,18 @@ export const ForceFeedbackPanel: React.FC<Props> = ({ options, data, width, heig
5959
while (data.series[ProcessIndex].fields[1].labels?.processid === nodeProcess) {
6060
//Add Filter
6161
if (options.UseFilterFilename) {
62+
//Split filter
63+
var FilterWrite = options.FilterFilename.split(',');
6264
let lFileName: any = [];
6365
let nFN: any = [];
6466
//Write
6567
lFileName.push(data.series[ProcessIndex + data.series.length / 2].fields[1].values);
6668
for (let i = 0; i < lFileName[0].buffer.length; i++) {
67-
if (lFileName[0].buffer[i].includes(options.FilterFilename)) {
68-
nFN.push(lFileName[0].buffer[i]);
69+
for (let j = 0; j < FilterWrite.length; j++) {
70+
if (lFileName[0].buffer[i].includes(FilterWrite[j])) {
71+
nFN.push(lFileName[0].buffer[i]);
72+
j = FilterWrite.length;
73+
}
6974
}
7075
}
7176
writeNodes.push(nFN);
@@ -96,13 +101,18 @@ export const ForceFeedbackPanel: React.FC<Props> = ({ options, data, width, heig
96101
while (data.series[ProcessIndex].fields[1].labels?.processid === nodeProcess) {
97102
//Add Filter
98103
if (options.UseFilterFilename) {
104+
//Split filter
105+
var Filters = options.FilterFilename.split(',');
99106
let lFileName: any = [];
100107
let nFN: any = [];
101108
//Read
102109
lFileName.push(data.series[ProcessIndex + data.series.length / 2].fields[1].values);
103110
for (let i = 0; i < lFileName[0].buffer.length; i++) {
104-
if (lFileName[0].buffer[i].includes(options.FilterFilename)) {
105-
nFN.push(lFileName[0].buffer[i]);
111+
for (let j = 0; j < Filters.length; j++) {
112+
if (lFileName[0].buffer[i].includes(Filters[j])) {
113+
nFN.push(lFileName[0].buffer[i]);
114+
j = Filters.length;
115+
}
106116
}
107117
}
108118
readNodes.push(nFN);
@@ -165,44 +175,44 @@ export const ForceFeedbackPanel: React.FC<Props> = ({ options, data, width, heig
165175
addingNodes = true;
166176
}
167177

168-
//Get all Threads of the Process
169-
for (let i = 0; i < nodeThreads.length; i++) {
170-
//Check for existing nodes w/o ProcessNode, skip existing nodes
171-
if (
172-
!nodes
173-
.slice(1)
174-
.map((a: any) => a.name)
175-
.includes(nodeThreads[i])
176-
) {
177-
//Assign Colour
178-
let nodeColour: any;
179-
//Amount Read/Write
180-
let amountReadWrite: any = [0, 0];
181-
for (let j = 0; j < attributeFileName[i].length; j++) {
182-
if (attributeFileName[i][j] !== undefined) {
183-
if (attributeFileName[i][j] === 'Read') {
184-
amountReadWrite[0]++;
185-
} else if (attributeFileName[i][j] === 'Write') {
186-
amountReadWrite[1]++;
178+
//Get all Threads of the Process
179+
for (let i = 0; i < nodeThreads.length; i++) {
180+
//Check for existing nodes w/o ProcessNode, skip existing nodes
181+
if (
182+
!nodes
183+
.slice(1)
184+
.map((a: any) => a.name)
185+
.includes(nodeThreads[i])
186+
) {
187+
//Assign Colour
188+
let nodeColour: any;
189+
//Amount Read/Write
190+
let amountReadWrite: any = [0, 0];
191+
for (let j = 0; j < attributeFileName[i].length; j++) {
192+
if (attributeFileName[i][j] !== undefined) {
193+
if (attributeFileName[i][j] === 'Read') {
194+
amountReadWrite[0]++;
195+
} else if (attributeFileName[i][j] === 'Write') {
196+
amountReadWrite[1]++;
197+
}
187198
}
188199
}
200+
nodeColour = ColourMix(amountReadWrite);
201+
nodes.push({
202+
index: nodeNumber,
203+
prefix: 'ThreadID: ',
204+
name: nodeThreads[i],
205+
affiliatedPrefix: 'File Access: ',
206+
affiliated: 'Read: ' + amountReadWrite[0],
207+
affiliated2: 'Write: ' + amountReadWrite[1],
208+
r: 5,
209+
writtenBytes: data.series[ProcessIndex - nodeThreads.length + i].fields[1].values.get(0),
210+
colour: nodeColour,
211+
});
212+
nodeNumber += 1;
213+
addingNodes = true;
189214
}
190-
nodeColour = ColourMix(amountReadWrite);
191-
nodes.push({
192-
index: nodeNumber,
193-
prefix: 'ThreadID: ',
194-
name: nodeThreads[i],
195-
affiliatedPrefix: 'File Access: ',
196-
affiliated: 'Read: ' + amountReadWrite[0],
197-
affiliated2: 'Write: ' + amountReadWrite[1],
198-
r: 5,
199-
writtenBytes: data.series[ProcessIndex - nodeThreads.length + i].fields[1].values.get(0),
200-
colour: nodeColour,
201-
});
202-
nodeNumber += 1;
203-
addingNodes = true;
204215
}
205-
}
206216

207217
//Get all traced_filenames for each process
208218
let IndexFilenamePerThread = nodeFileName.length + 1; //helpNodes to check the filenames of each thread instead of all filenames
@@ -280,13 +290,12 @@ export const ForceFeedbackPanel: React.FC<Props> = ({ options, data, width, heig
280290
for (let i = 1; i < 1 + nodeThreads.length; i++) {
281291
let targetT = nodes[i];
282292
changeNodeSize(nodes[targetT.index]);
283-
//TODO
284293
//Link colour depending on wether last action was read or write? => Needed for Threads?
285-
let link_colour = '#003f5c';
294+
//let link_colour = '#003f5c';
286295
nodesLinks.push({
287296
source: sourceT.index,
288297
target: targetT.index,
289-
colour: link_colour,
298+
colour: targetT.colour,
290299
});
291300
}
292301
//Assign Filesystem
@@ -296,67 +305,66 @@ export const ForceFeedbackPanel: React.FC<Props> = ({ options, data, width, heig
296305
for (let k = 0; k < nodeFileName[i].length; k++) {
297306
let targetFn = nodes[nodeThreads.length + j];
298307
j++;
299-
//TODO
300308
//LinkColour Filename
301309
//Link colour depending on wether last action was read or write
302310
nodesLinks.push({
303311
source: sourceFn,
304312
target: targetFn.index - 1,
305313
colour: targetFn.colour,
306314
});
315+
}
316+
}
307317
}
308-
}
309-
}
310318

311-
//Colourmix
312-
function ColourMix(lAmountReadWrite: any) {
313-
//Colour selection
314-
let colourNode: string;
315-
let RdWrtPercentage = 0;
316-
//Check for 0
317-
if (!(lAmountReadWrite[0] === 0 && lAmountReadWrite[1] === 0)) {
318-
if (lAmountReadWrite[1] === 0 && lAmountReadWrite[0] !== 0) {
319-
//onlyread
320-
RdWrtPercentage = 1;
321-
} else if (lAmountReadWrite[1] !== 0) {
322-
//only writes & mixed
323-
RdWrtPercentage = lAmountReadWrite[0] / lAmountReadWrite[1];
319+
//Colourmix
320+
function ColourMix(lAmountReadWrite: any) {
321+
//Colour selection
322+
let colourNode: string;
323+
let RdWrtPercentage = 0;
324+
//Check for 0
325+
if (!(lAmountReadWrite[0] === 0 && lAmountReadWrite[1] === 0)) {
326+
if (lAmountReadWrite[1] === 0 && lAmountReadWrite[0] !== 0) {
327+
//onlyread
328+
RdWrtPercentage = 1;
329+
} else if (lAmountReadWrite[1] !== 0) {
330+
//only writes & mixed
331+
RdWrtPercentage = lAmountReadWrite[0] / lAmountReadWrite[1];
332+
}
333+
//build mixture of those Read = #323264, Write = #643232
334+
let redprop = (32 + 100 * (1 - RdWrtPercentage)).toString(16).substring(0, 2);
335+
let blueprop = (32 + 132 * RdWrtPercentage).toString(16).substring(0, 2);
336+
colourNode = '#' + redprop + '20' + blueprop;
337+
return colourNode;
338+
} else {
339+
return '#888888';
340+
}
324341
}
325-
//build mixture of those Read = #323264, Write = #643232
326-
let redprop = (32 + 100 * (1 - RdWrtPercentage)).toString(16).substring(0, 2);
327-
let blueprop = (32 + 132 * RdWrtPercentage).toString(16).substring(0, 2);
328-
colourNode = '#' + redprop + '20' + blueprop;
329-
return colourNode;
330-
} else {
331-
return '#888888';
332-
}
333-
}
334342

335-
//Process and Threads
336-
function forceSimulation(_callback: () => void) {
337-
//Draw Threads and Process
338-
let simulationThread = d3
339-
.forceSimulation(nodes.slice(0, nodeThreads.length + 1))
340-
.force('charge', d3.forceManyBody().strength(-200))
341-
.force('link', d3.forceLink().links(nodesLinks.slice(0, nodeThreads.length)).distance(100).strength(4))
342-
.stop();
343-
simulationThread.tick(500);
343+
//Process and Threads
344+
function forceSimulation(_callback: () => void) {
345+
//Draw Threads and Process
346+
let simulationThread = d3
347+
.forceSimulation(nodes.slice(0, nodeThreads.length + 1))
348+
.force('charge', d3.forceManyBody().strength(-200))
349+
.force('link', d3.forceLink().links(nodesLinks.slice(0, nodeThreads.length)).distance(100).strength(4))
350+
.stop();
351+
simulationThread.tick(500);
344352

345-
//Draw Filenames
346-
const otherThreads = Array.from({ length: nodeThreads.length - 1 }, () => []);
347-
const lData = [nodes.slice(0, nodeThreads.length + 1), ...otherThreads].concat(
348-
nodes.slice(nodeThreads.length + 1)
349-
);
350-
const lLinks = nodesLinks.slice(nodeThreads.length);
351-
let simulationFilename = d3
352-
.forceSimulation(lData)
353-
.force('charge', d3.forceManyBody().strength(-40))
354-
.force('link', d3.forceLink().links(lLinks).distance(50).strength(4))
355-
.stop();
356-
simulationFilename.tick(500);
353+
//Draw Filenames
354+
const otherThreads = Array.from({ length: nodeThreads.length - 1 }, () => []);
355+
const lData = [nodes.slice(0, nodeThreads.length + 1), ...otherThreads].concat(
356+
nodes.slice(nodeThreads.length + 1)
357+
);
358+
const lLinks = nodesLinks.slice(nodeThreads.length);
359+
let simulationFilename = d3
360+
.forceSimulation(lData)
361+
.force('charge', d3.forceManyBody().strength(-40))
362+
.force('link', d3.forceLink().links(lLinks).distance(50).strength(4))
363+
.stop();
364+
simulationFilename.tick(500);
357365

358-
_callback();
359-
}
366+
_callback();
367+
}
360368

361369
function drawForceGraph() {
362370
const margin = { left: 20, top: 10, right: 20, bottom: 10 };
@@ -542,14 +550,14 @@ function forceSimulation(_callback: () => void) {
542550
}
543551
}
544552

545-
function runSimulation() {
546-
addNodes(() => addLinks());
547-
forceSimulation(drawForceGraph);
548-
fixateNodes();
549-
//Add Links to sS?
550-
sessionStorage.setItem('nodes', JSON.stringify(nodes));
551-
sessionStorage.setItem('links', JSON.stringify(nodesLinks));
552-
}
553+
function runSimulation() {
554+
addNodes(() => addLinks());
555+
forceSimulation(drawForceGraph);
556+
fixateNodes();
557+
//Add Links to sS?
558+
sessionStorage.setItem('nodes', JSON.stringify(nodes));
559+
sessionStorage.setItem('links', JSON.stringify(nodesLinks));
560+
}
553561

554562
if (data.series.length === 0) {
555563
d3.select('#area').selectAll('*').remove();

Live-Tracing/grafana-plugins/force-graph-plugin/src/module.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,26 @@ export const plugin = new PanelPlugin<PanelOptions>(ForceFeedbackPanel).setPanel
77
.addBooleanSwitch({
88
path: 'UseFilterFilename',
99
name: 'Warning:',
10-
description: 'Not using the filter may lead to a messy/unreadable Forcegraph due to too many Datapoints.',
10+
description: 'Not using the filter a lead to a messy/unreadable Forcegraph due to too many Datapoints.',
1111
defaultValue: defaultPanelOptions.UseFilterFilename,
1212
})
1313
.addTextInput({
1414
path: 'FilterFilename',
1515
name: 'Only show Filenames containing:',
16-
description: 'Plugin will show Process with related Threads and Filenames',
16+
description: "Plugin will show Process with related Threads and Filenames. Split Inputs with ','.",
1717
defaultValue: defaultPanelOptions.FilterFilename,
1818
})
19+
.addBooleanSwitch({
20+
path: 'UseNegativeFilterFilename',
21+
name: '',
22+
defaultValue: defaultPanelOptions.UseNegativeFilterFilename,
23+
})
24+
.addTextInput({
25+
path: 'NegFilterFilename',
26+
name: 'Filter Filenames containing:',
27+
description: "Plugin will show Process with related Threads and Filenames. Split Inputs with ','.",
28+
defaultValue: defaultPanelOptions.NegFilterFilename,
29+
})
1930
.addBooleanSwitch({
2031
path: 'UseWrite',
2132
name: 'Show written Data.',

Live-Tracing/grafana-plugins/force-graph-plugin/src/types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,17 @@
44
export interface PanelOptions {
55
UseFilterFilename: any;
66
FilterFilename: string;
7+
UseNegativeFilterFilename: any;
8+
NegFilterFilename: string;
79
UseWrite: any;
810
UseRead: any;
911
}
1012

1113
export const defaultPanelOptions: PanelOptions = {
1214
UseFilterFilename: true,
1315
FilterFilename: 'pfs',
16+
UseNegativeFilterFilename: false,
17+
NegFilterFilename: '',
1418
UseWrite: true,
1519
UseRead: true,
1620
};

0 commit comments

Comments
 (0)