mirror of
https://github.com/akvorado/akvorado.git
synced 2025-12-11 22:14:02 +01:00
doc: update with a few words about the console
This commit is contained in:
@@ -87,8 +87,69 @@ instances are still running an older version).
|
|||||||
|
|
||||||
## Console service
|
## Console service
|
||||||
|
|
||||||
`akvorado console` starts the console service. Currently, only this
|
`akvorado console` starts the console service. It provides a web
|
||||||
documentation is accessible through this service.
|
console. The home page is a simple dashboard with a few metrics, some
|
||||||
|
graphs and a recent example of flow. The console also contains this
|
||||||
|
documentation. The most interesting page is the “visualize” tab which
|
||||||
|
allows a user to explore data using graphs.
|
||||||
|
|
||||||
|
### Graph options
|
||||||
|
|
||||||
|
The collapsible panel on the left has several options to change the
|
||||||
|
aspect of the graph.
|
||||||
|
|
||||||
|
- Four graph types are provided: “stacked”, “lines” and “grid” to
|
||||||
|
display time series and “sankey” to show flow distributions between
|
||||||
|
various dimensions.
|
||||||
|
|
||||||
|
- The time range can be set from a list of preset or directly using
|
||||||
|
natural language. The parsing is done by
|
||||||
|
[SugarJS](https://sugarjs.com/dates/#/Parsing) which provides
|
||||||
|
examples of what can be done. Another alternative is to look at the
|
||||||
|
presets. Dates can also be entered using their ISO format:
|
||||||
|
`2022-05-22 12:33` for example.
|
||||||
|
|
||||||
|
- A set of dimensions can be selected. For time series, dimensions are
|
||||||
|
converted to series. They are stacked when using “stacked”,
|
||||||
|
displayed as simple lines with “lines” and displayed in a grid with
|
||||||
|
“grid”. The grid representation can be useful if you need to compare
|
||||||
|
the volume of each dimension. For sankey graphs, dimensions are
|
||||||
|
converted to nodes. In this case, at least two dimensions need to be
|
||||||
|
selected.
|
||||||
|
|
||||||
|
- Akvorado will only retrieve a limited number of series and the
|
||||||
|
"limit" parameter tells how many. The remaining values are
|
||||||
|
categorized as "Other".
|
||||||
|
|
||||||
|
- The filter box contains an SQL-like expression to limit the data to
|
||||||
|
be graphed.
|
||||||
|
|
||||||
|
The URL contains the encoded parameters and can be used to share with
|
||||||
|
others. However, currently, no stability of the options are
|
||||||
|
guaranteed, so an URL may stop working after a few upgrades.
|
||||||
|
|
||||||
|
### Filter language
|
||||||
|
|
||||||
|
The filter language looks like SQL with a few variations. Fields
|
||||||
|
listed as dimensions can usually be used. Accepted operators are `=`,
|
||||||
|
`!=`, `<`, `<=`, `>`, `>=`, `IN`, `LIKE`, `ILIKE`, when they make
|
||||||
|
sense. Here are a few examples:
|
||||||
|
|
||||||
|
- `InIfBoundary = external` only selects flows whose incoming
|
||||||
|
interface was classified as external. The value should not be
|
||||||
|
quoted.
|
||||||
|
- `InIfConnectivity = "ix"` selects flows whose incoming interface is
|
||||||
|
connected to an IX.
|
||||||
|
- `SrcAS = AS12322`, `SrcAS = 12322`, `SrcAS IN (12322, 29447)`
|
||||||
|
limits the source AS number of selected flows.
|
||||||
|
- `SrcAddr = 203.0.113.4` only selects flows with the specified
|
||||||
|
address. Note that filtering on IP addresses is usually slower.
|
||||||
|
- `ExporterName LIKE th2-%` selects flows coming from routers
|
||||||
|
starting with `th2-`.
|
||||||
|
|
||||||
|
The final SQL query sent to ClickHouse is logged inside the console
|
||||||
|
after a successful request. It should be noted than using ports or
|
||||||
|
addresses prevent the use of aggregated data and are therefore slower.
|
||||||
|
|
||||||
## Other commands
|
## Other commands
|
||||||
|
|
||||||
|
|||||||
@@ -142,6 +142,51 @@ capacity.
|
|||||||
Testing is done by another implementation of an [SNMP
|
Testing is done by another implementation of an [SNMP
|
||||||
agent](https://github.com/salyercat/GoSNMPServer).
|
agent](https://github.com/salyercat/GoSNMPServer).
|
||||||
|
|
||||||
|
## Web console
|
||||||
|
|
||||||
|
The web console is built as a REST API with a single page application
|
||||||
|
on top of it.
|
||||||
|
|
||||||
|
### REST API
|
||||||
|
|
||||||
|
The REST API is mostly built using the [Gin
|
||||||
|
framework](https://gin-gonic.com/) which removes some boilerplate
|
||||||
|
compared to using pure Go. Also, it uses the [validator
|
||||||
|
package](https://github.com/go-playground/validator) which implements
|
||||||
|
value validations based on tags. The validation options are quite
|
||||||
|
rich.
|
||||||
|
|
||||||
|
### Single page application
|
||||||
|
|
||||||
|
The SPA is built using mostly the following components:
|
||||||
|
|
||||||
|
- [Yarn](https://yarnpkg.com/) as a package manager,
|
||||||
|
- [Vite](https://vitejs.dev/) as a builder,
|
||||||
|
- [Vue](https://vuejs.org/) as the reactive JavaScript framework,
|
||||||
|
- [TailwindCSS](https://tailwindcss.com/) for styling pages directly inside HTML,
|
||||||
|
- [Headless UI](https://headlessui.dev/) for some unstyled UI components,
|
||||||
|
- [ECharts](https://echarts.apache.org/) to plot charts.
|
||||||
|
|
||||||
|
There is no full-blown component library despite the existence of many candidates:
|
||||||
|
|
||||||
|
- [Vuetify](https://vuetifyjs.com/) is only compatible with Vue 2.
|
||||||
|
- [BootstrapVue](https://bootstrap-vue.org/) is only compatible with Vue 2.
|
||||||
|
- [PrimeVue](https://www.primefaces.org/primevue/) is quite heavyweight and many stuff are not opensource.
|
||||||
|
- [VueTailwind](https://www.vue-tailwind.com/) would be the perfect match but it is not compatible with Vue 2.
|
||||||
|
- [Naive UI](https://www.naiveui.com/) may be a future option but the
|
||||||
|
styling is not using TailwindCSS which is annoying for responsive
|
||||||
|
stuff, but we can just stay away from the proposed layout.
|
||||||
|
|
||||||
|
So, currently, components are mostly taken from
|
||||||
|
[Flowbite](https://flowbite.com/), copy/pasted or from Headless UI and
|
||||||
|
styled like Flowbite.
|
||||||
|
|
||||||
|
Use of TailwindCSS is also a strong choice. Their
|
||||||
|
[documentation](https://tailwindcss.com/docs/utility-first) explains
|
||||||
|
this choice. It makes sense but this is sometimes a burden. Many
|
||||||
|
components are scattered around the web and when there is no need for
|
||||||
|
JS, it is just a matter of copy/pasting and customizing.
|
||||||
|
|
||||||
## Other components
|
## Other components
|
||||||
|
|
||||||
The core component is the main one. It takes the other as dependencies
|
The core component is the main one. It takes the other as dependencies
|
||||||
|
|||||||
@@ -133,7 +133,12 @@ const { data, isFetching, aborted, abort, canAbort, error } = useFetch("", {
|
|||||||
async afterFetch(ctx) {
|
async afterFetch(ctx) {
|
||||||
// Update data. Not done in a computed value as we want to keep the
|
// Update data. Not done in a computed value as we want to keep the
|
||||||
// previous data in case of errors.
|
// previous data in case of errors.
|
||||||
const { data } = ctx;
|
const { data, response } = ctx;
|
||||||
|
console.groupCollapsed("SQL query");
|
||||||
|
console.info(
|
||||||
|
response.headers.get("x-sql-query").replace(/ {2}( )*/g, "\n$1")
|
||||||
|
);
|
||||||
|
console.groupEnd();
|
||||||
fetchedData.value = {
|
fetchedData.value = {
|
||||||
...data,
|
...data,
|
||||||
dimensions: payload.value.dimensions,
|
dimensions: payload.value.dimensions,
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ func (c *Component) graphHandlerFunc(gc *gin.Context) {
|
|||||||
}
|
}
|
||||||
sqlQuery = c.queryFlowsTable(sqlQuery,
|
sqlQuery = c.queryFlowsTable(sqlQuery,
|
||||||
query.Start, query.End, resolution)
|
query.Start, query.End, resolution)
|
||||||
gc.Header("X-SQL-Query", sqlQuery)
|
gc.Header("X-SQL-Query", strings.ReplaceAll(sqlQuery, "\n", " "))
|
||||||
|
|
||||||
results := []struct {
|
results := []struct {
|
||||||
Time time.Time `ch:"time"`
|
Time time.Time `ch:"time"`
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ func (c *Component) sankeyHandlerFunc(gc *gin.Context) {
|
|||||||
// Prepare and execute query
|
// Prepare and execute query
|
||||||
sqlQuery = c.queryFlowsTable(sqlQuery,
|
sqlQuery = c.queryFlowsTable(sqlQuery,
|
||||||
query.Start, query.End, resolution)
|
query.Start, query.End, resolution)
|
||||||
gc.Header("X-SQL-Query", sqlQuery)
|
gc.Header("X-SQL-Query", strings.ReplaceAll(sqlQuery, "\n", " "))
|
||||||
results := []struct {
|
results := []struct {
|
||||||
Xps float64 `ch:"xps"`
|
Xps float64 `ch:"xps"`
|
||||||
Dimensions []string `ch:"dimensions"`
|
Dimensions []string `ch:"dimensions"`
|
||||||
|
|||||||
Reference in New Issue
Block a user