Skip to main content

Park tag enrichment plugin

· One min read

The plugin dereferences Park tags to display park name and parkCode.

For the plugin to work, Spider tags must be configured to extract park id from the HTTP requests & responses.

Parameters​

The plugin takes 3 parameters:

  • Environment: Streetsmart environment to calls to dereference the filters
  • Login & password: Account used to connect to Streetsmart
    • The account must exists on the selected environment.
    • For now, it has been created in SIT0, SIT1 and SVT2

Result​

  • In grid

  • In filter

  • In smart filters

  • In details

  • In stats

  • In excel exports

Code​

The code is available in Flowbird bitbucket repo: https://bitbucket.org/parkeon-ondemand/sss-park-tag-enrichment-spiderplugin

The plugin:

  • Request /park/{id} if less than 5 parks to resolve
  • Build queryString queries if more than 5 parks, by grouping by 25 parks buckets
  • Cache the results not to ask several times
  • Blocks parallel requests not to ask simultaneously resolving of the same park

All this in a few lines, many nice patterns to reuse !! :D

Streetsmart token decoder plugin

· One min read

The plugin extract Streetsmart rights from JWT token.

  • The rights are displayed in a JSON editor for better readibility and folding
  • The multitenant filters (parks or others) are extracted and dereferenced

Parameters​

The plugin takes 3 parameters:

  • Environment: Streetsmart environment to calls to dereference the filters
  • Login & password: Account used to connect to Streetsmart
    • The account must exists on the selected environment.
    • For now, it has been created in SIT0, SIT1 and SVT2

Result​

Code​

The code is available in Flowbird bitbucket repo: https://bitbucket.org/parkeon-ondemand/sss-token-decoder-spiderplugin/

Copy to clipboard of arrays configuration components

· One min read

Configuration components such as the below one already allowed importing settings from spreadsheets by copy pasting in the first cell:

Now, they include an export feature to the clipboard. At the top right, you may copy the settings to the clipboard, including or not the headers:

The output can be pasted to Excel, Google sheet or ...

It can then be saved for later, or edited. Then pasted back:

Custom content types

· One min read

As requested by Remi L,

  • When the request or response body does not include any content-type whereas there is a body, it is possible to chose a custom content-type to benefit from nice payload formatting and color syntaxing.

In the HTTP Request or Response time, you may chose the format of the payload:

The payload is registered and associated to the request template so that it is remembered and applied for all same requests.

You may see and edit registered association in the HTTP specific settings:

Map visual improvements: latency on link, tooltips actions, details view & fixed positions

· 2 min read

I improved map display to improve the statistic information display over the arrows.

Now the latency of communications is display inside the arrows, with color scale:

  • Strong green for the fastest
  • Strong red for the fastest

This allows quick identification of the longest calls / API in a glance.

In order not to overload the UI, the amount of rows on which to display latency can be set in settings:

With this new feature, the network map displays many information at one glance to identify exceptions:

  • Amount of data exchanged is shown in
    • Size of nodes
    • Strength of links
  • Amount of errors is shown in
    • Color of nodes
    • Color of links
  • Fastest / slowest links are shown in
    • Latency bullet

Nodes and Links tooltips on map have been improved for easier usage.

  • The pin and the open-details actions have move moved on top of the tooltips.
  • Two icons have been added to:
    • Add to filters the node / link (positive filtering)
    • Remove from view the node / link (negative filtering)

Details view for Nodes and Links have been enriched with the performance statistics gathered to build the map, and complete list of templates and stats.

Fixed positions​

When you position a node manually, its position gets locked an remembered on the server.

This wasn't working properly lately, because of the temporal indices used to store the node naming and positions.

Now the positions of nodes is saved in users own settings. Only impacting each users view. The position is saved based on the service name, and kept through reloads and nodes history. Much better. You may easily unlock a position by clicking on the lock, as before.

Pause background tasks when Spider is not visible.

· One min read

Previously, when Spider tab was hidden in the browser, the background refresh tasks where still running, but browsers such as Chrome where blocking the network calls and slowing down Javascript timers.

This was generating a lot of error messages when the tab was made visible again.

After some documentation reading, Spider now listens to the event

visibilitychange

to know when it is visible on not, and deactivates background tasks when hidden, to restart them when made visible again.

No more pile of error messages in the morning! :)

Plugin framework to extend Spider !! 8-O

· 6 min read

I was wondering for some time how to improve Spider usage to add specific features for projects or system being monitored while not coupling Spider code to those systems, such as Streetsmart.

I found a solution on ideas that I pushed on Streetsmart business apps architecture. A solution to extend Spider's UI with plugins.

What are Spider plugins?​

Like nano frontends that add UI features into various parts of the application.

They are standalone Javascript files, implementing a specific signature depending on the plugin type. These plugins must come with their own manifest file providing metadata for the UI, and parameters definition.

The manifest is loaded in Spider UI, thus registering the plugin.

On the UI features accepting the plugins, they are loaded and called if activated (only then), and the results are injected in the UI.

Loading plugins​

Plugins are loaded in the Settings details:

Once loaded, they are displayed in the same tab, with various options:

You may:

  • Enable or disable them
  • Reload them (useful when developing them ;) )
  • Remove them
  • And edit parameters

Parameters​

Each plugin may require one to many parameters to work or adjust its work. Parameters are defined in the plugin manifest.

For now, accepted parameters types are:

  • Text - free input
  • Password - free input
  • Select - list of options : labels and values

Parameters may have a default values and validation constraints, as defined in the manifest. Parameters and loaded plugins are saved in users settings, except for password values. Those are not saved on server side, only locally.

Manifest definition​

{
"@id": identifier for the plugin
"@version": version,
"@type": type of the plugin, as defined in Spider
"manifest": location of the manifest, for reload
"dist": location of the code
"name": name for the UI
"description": description for the UI
"parameters": [ list of parameters
{
"name": name of the parameter in the UI
"description": description of the parameter for the tooltip
"valueName": name of the parameter expected by the plugin
"valueType": type of input (TEXT, PASSWORD, SELECT)
"valueRequired": boolean
"defaultValue": any
"maxValue": for numbers / later
"minValue":for numbers / later
"multipleValues": if many values may be selected
"stepValue": if values are generated from min to max
"valueMaxLength": max length if string
"valueMinLength": min length if string
"valuePattern": regex if string
"optionValue": [ list of possible options for selects
{
"label": string to display
"value": any
}
],
"onlyOptionValuesAllowed": if select accepts unknown values
}
]
}

Plugin common signature​

{
inputs: {},
parameters: {},
callbacks: {setXXX, onShowInfo, onShowError, onShowWarning },
libs: {React}
}

When called, the plugin is called with the above signature:

  • inputs: specific inputs defined by the plugin type
  • parameters: specific inputs defined by the plugin itself, in the manifest, the keys being the valueName
  • callbacks:
    • functions to emit info, warning or error messages (toasts)
    • callback to return the result
  • libs: libraries provided to the plugin
    • React is provided and may be used to format the output

Plugin injection​

async function myOwnPlugin({
inputs: {},
parameters: {},
callbacks: {setXXX, onShowInfo, onShowError, onShowWarning },
libs: {React}
}){
...
}

function plugin(props){
myOwnPlugin(props).catch(e => {
props.callbacks.onShowError('myOwnPlugin: Could not work!');
console.log(e);
});
}

plugin\['@id'\] = 'my-own-plugin';
plugin\['@type'\] = 'http-headers-decode-plugin';
plugin\['@version'\] = '1.0'

if(window.spiderPlugins){
if(!window.spiderPlugins.find(p => p\['@id'\] === plugin\['@id'\])){
window.spiderPlugins = \[...window.spiderPlugins, plugin\]
}
}
else{
window.spiderPlugins = \[plugin\]
}
  • Plugins must load themselves inside windows.spiderPlugins array.
  • They may be promises and perform API calls
  • They must attach their @id, @type and @version to the function. @id and @type must be the same as in the manifest.
  • The result of the plugin should be returned
    • As the promise result
    • And by the callback
  • You're advise to copy the code above :)

Available plugin types​

http-headers-decode-plugin​

These plugins allow decoding HTTP headers, in request or in response, to reveal their inner data.

This was the original plugin need/idea: decoding Streetsmart rights that are compressed inside the JWT token.

Signature​
{
inputs: {part, header, value},
parameters: {env, login, password},
callbacks: {setDecodedHeaders, onShowInfo, onShowError, onShowWarning },
libs: {React}
}

The plugin is called for each header.

Inputs​
  • part: 'req' for request headers or 'res' for response header
  • header: name of the header, in lower case
  • value: the header value
Output​

setDecodedHeaders callback expects an array of objects with this structure:

{
key: String, label to display in the UI
value: Any, value to display
format: String, format of the value
decoded: Boolean, whether or not the header is decoded (gray background in the UI)
}
  • format may be one of:
    • application/json, application/xml --> displayed in ACE editor
    • text/plain or react --> displayed as such
examples​
  • Decoding Streetsmart rights

  • Decoding certificates

tag-enrichment-plugin​

This plugin extends the tag extraction feature by allowing to dereference / enrich a tag from data of your own system and inject these in the UI.

For instance, a tag could extract the city id of the client of the requests, and get the city name from the system under monitoring. Then filtering becomes easier, and Excel extract, statistics and grid becomes more meaningful.

Signature​
{
inputs: {name, values, mode},
parameters: {basePath, login, password},
callbacks: {setDecodedTags, onShowInfo, onShowError, onShowWarning },
libs: {React}
}

The plugin is called:

  • For each row, and each displayed Tag in the Grid or Excel export
  • For each group for stats grouped by Tag and Excel export
  • For each Tag in the HTTP details panel
  • For each Tag and all Tag values for the Filters component in the grid header

Depending on the call, the output is requested in REACT components mode (grids and details) or in TEXT mode (Excel, filters)

Input​
  • name:
  • values: array of tag values
  • mode: 'REACT' or 'TEXT' for the output type.
Output​

Expected output expects an array of decoded values, in the same order, without holes as the values array input.

Output must be sent both:

  • Using setDecodedTags callback
  • With a return value (of the promise)
ExampleS​

Resolving parks names:

  • In grid

  • In filter

  • In smart filters

  • In details

  • In stats

  • In excel exports

Plugin example​

An http-headers-decode-plugin plugin example is available in https://gitlab.com/TincaTibo/certificate-decoder-spider-plugin/.

It may be reused and extended at will.

Usability and speed improvement on Timeline!

· One min read

Before, when starting Spider, the timelline was computing the oldest and newest data of the Whisperer to set the starting range of the Timeline.

This query was costly on Elasticsearch side, as it required to load and search on all indices. Which, in the end, generated some timeouts the first times.

I changed the process, and now, the default timeline range is set to current day for realtime whisperers, and computed to min and max only for upload type ones.

To accomodate this new process, you may now zoom out on the timeline from the start, until you reach some defined limit or until you're tired ;)

Less timeouts, faster startup, better UX. Happy zooming and sliding !!

Adapt JSON-LD contexts

· One min read

When opening a JSON-LD communication, you are allowed to choose another view to see it.

Thanks to the UI refactoring, it costed me almost nothing to provide an edit feature to these settings in the HTTP settings panel (and I had to find stuff to put there ;) ).