Dashboards¶
Dashboards are visualizations of incoming log data. While TeskaLabs LogMan.io comes with a library of preset dashboards, you can also create your own. View preset dashboards in the LogMan.io web app in Dashboards.
In order to create a dashboard, you need to write or copy a dashboard file in the Library.
Creating a dashboard file¶
Write dashboards in JSON.
Creating a blank dashboard
- In TeskaLabs LogMan.io, go to the Library.
- Click Dashboards.
- Click Create new item in Dashboards.
- Name the item, and click Create. If the new item doesn't appear immediately, refresh the page.
Copying an existing dashboard
- In TeskaLabs LogMan.io, go to the Library.
- Click Dashboards.
- Click on the item you want to duplicate, then click the icon near the top. Click Copy.
- Choose a new name for the item, and click Copy. If the new item doesn't appear immediately, refresh the page.
Dashboard structure¶
Write dashboards in JSON, and be aware that they're case-sensitive.
Dashboards have two parts:
- The dashboard base: A query bar, time selector, refresh button, and options button
- Widgets: The visualizations (chart, graph, list, etc.)
Dashboard base
Include this section exactly as-is to include the query bar, time selector, refresh button, and options.
{
"Prompts": {
"dateRangePicker": true,
"filterInput": true,
"submitButton": true
Widgets¶
Widgets are made of datasource
and widget
pairs. When you write a widget, need to include both a datasource
section and a widget
section.
JSON formatting tips:
- Separate every
datasource
andwidget
section by a brace and a comma},
except for the final widget in the dashboard, which does not need a comma (see the full example) - End every line with a comma
,
except the final item in a section
Widget positioning
Each widget has layout lines, which dictate the size and position of the widget. If you don't include layout lines when you write the widget, the dashboard generates them automatically.
- Include the layout lines with the suggested values from each widget template, OR don't include any layout lines. (If you don't include any layout lines, make sure the final item in each section does NOT end with a comma.)
- Go to Dashboards in LogMan.io and resize and move the widget.
- When you move the widget on the Dashboards page, the dashboard file in the Library automatically generates or adjusts the layout lines accordingly. If you're working in the dashboard file in the Library and repositioning the widgets in Dashboards at the same time, make sure to save and refresh both pages after making changes on either page.
The order of widgets in your dashboard file does not determine widget position, and the order does not change if you reposition the widgets in Dashboards.
Naming
We recommend agreeing on naming conventions for dashboards and widgets within your organization to avoid confusion.
matchPhrase filter
For Elasticsearch data sources, use Lucene query syntax for the matchPhrase
value.
Colors
By default, pie chart and bar chart widgets use a blue color scheme. To change the color scheme, insert "color":"(color scheme)"
directly before the layout lines.
- Blue: No extra lines necessary
- Purple:
"color":"sunset"
- Yellow:
"color":"warning"
- Red:
"color":"danger"
Troubleshooting JSON
If you get an error message about JSON formatting when trying to save the file:
- Follow the recommendation of the error message specifying what the JSON is "expecting" - it might mean that you're missing a required key-value pair, or the punctuation is incorrect.
- If you can't find the error, double-check that your formatting is consistent with other functional dashboards.
If your widget does not display correctly:
- Make sure the value of
datasource
matches in both the data source and widget sections. - Check for spelling errors or query structure issues in any fields referenced and in fields specified in the
matchphrase
query. - Check for any other typos or inconsistencies.
- Check that the log source you are referencing is connected.
Use these examples as guides. Click the icons to learn what each line means.
Bar charts¶
A bar chart displays values with vertical bars on an x and y-axis. The length of each bar is proportional to the data it represents.
Bar chart JSON example:
"datasource:office365-email-aggregated": { #(1)
"type": "elasticsearch", #(2)
"datetimeField": "@timestamp", #(3)
"specification": "lmio-{{ tenant }}-events*", #(4)
"aggregateResult": true, #(5)
"matchPhrase": "event.dataset:microsoft-office-365 AND event.action:MessageTrace" #(6)
},
"widget:office365-email-aggregated": { #(7)
"datasource": "datasource:office365-email-aggregated", #(8)
"title": "Sent and received emails", #(9)
"type": "BarChart", #(10)
"xaxis": "@timestamp", #(11)
"yaxis": "o365.message.status", #(12)
"ylabel": "Count", #(13)
"table": true, #(14)
"layout:w": 6, #(15)
"layout:h": 4,
"layout:x": 0,
"layout:y": 0,
"layout:moved": false,
"layout:static": true,
"layout:isResizable": false
},
datasource
marks the beginning of the data source section as well as the name of the data source. The name doesn't affect the dashboard's function, but you need to refer to the name correctly in the widget section.- The type of data source. If you're using Elasticsearch, the value is
"elasticsearch"
- Indicates which field in the logs is the date and time field. For example, in Elasticsearch logs, which are parsed by the Elastic Common Schema (ECS), the date and time field is
@timestamp
. - Refers to the index from which to get data in Elasticsearch. The value
lmio-{{ tenant}}-events*
fits our index naming conventions in Elasticsearch, and{{ tenant }}
is a placeholder for the active tenant. The asterisk*
allows unspecified additional characters in the index name followingevents
. The result: The widget displays data from the active tenant. aggregateResult
set totrue
performs aggregation on the data before displaying it in the dashboard. In this case, the sent and received emails are being counted (sum calculated).- The query that filters for specific logs using Lucene query syntax. In this case, any data displayed in the dashboard must be from the Microsoft Office 365 dataset and have the value
MessageTrace
in the fieldevent.action
. widget
marks the beginning of the widget section as well as the name of the widget. The name doesn't affect the dashboard's function.- Refers to the data source section above which populates it. Make sure the value here matches the name of the corresponding data source exactly. (This is how the widget knows where to get data from.)
- Title of the widget that will display in the dashboard
- Type of widget
- The field from the logs whose values will be represented on the x axis
- The field from the logs whose values will be represented on the y axis
- Label for y axis that will display in the dashboard
- Setting
table
totrue
enables you to switch between chart view and table view on the widget in the dashboard. Choosingfalse
disables the chart-to-table feature. - See the note above about widget positioning for information about layout lines.
Bar chart widget rendered:
Bar chart template:
To create a bar chart widget, copy and paste this template into a dashboard file in the Library and fill in the values. Recommended layout values, the values specifying an Elasicsearch data source, and the value that organizes the bar chart by time are already filled in.
"datasource:Name of datasource": {
"type": "elasticsearch",
"datetimeField": "@timestamp",
"specification": "lmio-{{ tenant }}-events*",
"aggregateResult": true,
"matchPhrase": " "
},
"widget:Name of widget": {
"datasource": "datasource:office365-email-aggregated",
"title": "Widget display title",
"type": "BarChart",
"xaxis": "@timestamp",
"yaxis": " ",
"ylabel": " ",
"table": true,
"layout:w": 6,
"layout:h": 4,
"layout:x": 0,
"layout:y": 0,
"layout:moved": false,
"layout:static": true,
"layout:isResizable": false
},
Pie charts¶
A pie chart is a circle divided into slices, in which each slice represents a percentage of the whole.
Pie chart JSON example:
"datasource:office365-email-status": { #(1)
"datetimeField": "@timestamp", #(2)
"groupBy": "o365.message.status", #(3)
"matchPhrase": "event.dataset:microsoft-office-365 AND event.action:MessageTrace", #(4)
"specification": "lmio-{{ tenant }}-events*", #(5)
"type": "elasticsearch", #(6)
"size": 20 #(7)
},
"widget:office365-email-status": { #(8)
"datasource": "datasource:office365-email-status", #(9)
"title": "Received Emails Status", #(10)
"type": "PieChart", #(11)
"tooltip": true, #(12)
"table": true, #(13)
"layout:w": 6, #(14)
"layout:h": 4,
"layout:x": 6,
"layout:y": 0,
"layout:moved": false,
"layout:static": true,
"layout:isResizable": false
},
datasource
marks the beginning of the data source section, as well as the name of the data source. The name doesn't affect the dashboard's function, but you need to refer to the name correctly in the widget section.- Indicates which field in the logs is the date and time field. For example, in Elasticsearch logs, which are parsed by the Elastic Common Schema (ECS), the date and time field is
@timestamp
. - The field whose values will represent each "slice" of the pie chart. In this example, the pie chart will separate logs by their message status. There will be a separate slice for each of Delivered, Expanded, Quarantined, etc. to show the percentage occurrance of each message status.
- The query that filters for specific logs. In this case, only data from logs from the Microsoft Office 365 dataset with the value
MessageTrace
in the fieldevent.action
will be displayed. - Refers to the index from which to get data in Elasticsearch. The value
lmio-{{ tenant}}-events*
fits our index naming conventions in Elasticsearch, and{{ tenant }}
is a placeholder for the active tenant. The asterisk*
allows unspecified additional characters in the index name followingevents
. The result: The widget displays data from the active tenant. - The type of data source. If you're using Elasticsearch, the value is
"elasticsearch"
- How many values you want to display. Since this pie chart is showing the statuses of received emails, a
size
of 20 displays the top 20 status types. (The pie chart can have a maximum of 20 slices.) widget
marks the beginning of the widget section as well as the name of the widget. The name doesn't affect the dashboard's function.- Refers to the data source section above which populates it. Make sure the value here matches the name of the corresponding data source exactly. (This is how the widget knows where to get data from.)
- Title of the widget that will display in the dashboard
- Type of widget
- If
tooltip
is set totrue
: When you hover over each slice of the pie chart in the dashboard, a small informational window with the count of values in the slice pops up at your cursor. Iftooltip
is set tofalse
: The count window appears in the top left corner of the widget. - Setting
table
totrue
enables you to switch between chart view and table view on the widget in the dashboard. Choosingfalse
disables the chart-to-table feature. - See the note above about widget positioning for information about layout lines.
Pie chart template
To create a pie chart widget, copy and paste this template into a dashboard file in the Library and fill in the values. Recommended values as well as the values specifying an Elasicsearch data source are already filled in.
"datasource:Name of data source": {
"datetimeField": "@timestamp",
"groupBy": " ",
"matchPhrase": " ",
"specification": "lmio-{{ tenant }}-events*",
"type": "elasticsearch",
"size": 20
},
"widget:Name of widget": {
"datasource": "datasource:Name of data source",
"title": "Widget display title",
"type": "PieChart",
"tooltip": true,
"table": true,
"layout:w": 6,
"layout:h": 4,
"layout:x": 0,
"layout:y": 0,
"layout:moved": false,
"layout:static": true,
"layout:isResizable": false
},
Tables¶
A table displays text and numeric values from data fields that you specify.
Table widget example
"datasource:office365-email-failed-or-quarantined": { #(1)
"type": "elasticsearch", #(2)
"datetimeField": "@timestamp", #(3)
"specification": "lmio-{{ tenant }}-events*", #(4)
"size": 100, #(5)
"matchPhrase": "event.dataset:microsoft-office-365 AND event.action:MessageTrace AND o365.message.status:(Failed OR Quarantined)" #(6)
},
"widget:office365-email-failed-or-quarantined": { #(7)
"datasource": "datasource:office365-email-failed-or-quarantined", #(8)
"field:1": "@timestamp", #(9)
"field:2": "o365.message.status",
"field:3": "sender.address",
"field:4": "recipient.address",
"field:5": "o365.message.subject",
"title": "Failed or quarantined emails", #(10)
"type": "Table", #(11)
"dataPerPage": 9, #(12)
"layout:w": 12, #(13)
"layout:h": 4,
"layout:x": 0,
"layout:y": 0,
"layout:moved": false,
"layout:static": true,
"layout:isResizable": false
}
datasource
marks the beginning of the data source section, as well as the name of the data source. The name doesn't affect the dashboard's function, but you need to refer to the name correctly in the widget section.- The type of data source. If you're using Elasticsearch, the value is
"elasticsearch"
- Indicates which field in the logs is the date and time field. For example, in Elasticsearch logs, which are parsed by the Elastic Common Schema (ECS), the date and time field is
@timestamp
. - Refers to the index from which to get data in Elasticsearch. The value
lmio-{{ tenant}}-events*
fits our index naming conventions in Elasticsearch, and{{ tenant }}
is a placeholder for the active tenant. The asterisk*
allows unspecified additional characters in the index name followingevents
. The result: The widget displays data from the active tenant. - How many values you want to display. This table will have a maximum of 100 rows. You can set rows per page in
dataPerPage
below. - The query that filters for specific logs using Lucene query syntax. In this case, the widget displays data only from logs from the Microsoft Office 365 dataset with the value
MessageTrace
in the fieldevent.action
and a message status ofFailed
orQuarantined
. widget
marks the beginning of the widget section as well as the name of the widget. The name doesn't affect the dashboard's function.- Refers to the data source section above which populates it. Make sure the value here matches the name of the corresponding data source exactly. (This is how the widget knows where to get data from.)
- Each field is a column that will display in the table in the dashboard. In this example table of failed or quarantied emails, the table would display the timestamp, message status, sender address, recipient address, and the email subject for each log (which represents each email). Use as many fields as you want.
- Title of the widget that will display in the dashboard
- Type of widget
- The number of items displayed per page (at once) in the table
- See the note above about widget positioning for information about layout lines.
Table widget rendered:
Table widget template:
To create a table widget, copy and paste this template into a dashboard file in the Library and fill in the values. Recommended values as well as the values specifying an Elasicsearch data source are already filled in.
"datasource:Name of datasource": {
"type": "elasticsearch",
"datetimeField": "@timestamp",
"specification": "lmio-{{ tenant }}-events*",
"size": 100,
"matchPhrase": " "
},
"widget:Name of widget": {
"datasource": "Name of datasource",
"field:1": "@timestamp",
"field:2": " ",
"field:3": " ",
"field:4": " ",
"field:5": " ",
"title": "Widget title",
"type": "Table",
"dataPerPage": 9,
"layout:w": 12,
"layout:h": 4,
"layout:x": 0,
"layout:y": 0,
"layout:moved": false,
"layout:static": true,
"layout:isResizable": false
}
Single values¶
A value widget displays the most recent single value from the data field you specify.
"datasource:microsoft-exchange1": { #(1)
"datetimeField": "@timestamp", #(2)
"matchPhrase": "event.dataset:microsoft-exchange AND email.from.address:* AND email.to.address:*", #(3)
"specification": "lmio-{{ tenant }}-events*", #(4)
"type": "elasticsearch", #(5)
"size": 1 #(6)
},
"widget:fortigate1": { #(7)
"datasource": "datasource:microsoft-exchange1", #(8)
"field": "email.from.address", #(9)
"title": "Last Active User", #(10)
"type": "Value", #(11)
"layout:w": 4, #(12)
"layout:h": 1,
"layout:x": 0,
"layout:y": 0,
"layout:moved": false,
"layout:static": true,
"layout:isResizable": false
}
datasource
marks the beginning of the data source section, as well as the name of the data source. The name doesn't affect the dashboard's function, but you need to refer to the name correctly in the widget section.- Indicates which field in the logs is the date and time field. For example, in Elasticsearch logs, which are parsed by the Elastic Common Schema (ECS), the date and time field is
@timestamp
. - The query that filters for specific logs using Lucene query syntax. In this case, the widget displays data only from logs from the Microsoft Exchange dataset with ANY value (
*
) in theemail.from.address
andemail.to.address
fields. - Refers to the index from which to get data in Elasticsearch. The value
lmio-{{ tenant}}-events*
fits our index naming conventions in Elasticsearch, and{{ tenant }}
is a placeholder for the active tenant. The asterisk*
allows unspecified additional characters in the index name followingevents
. The result: The widget displays data from the active tenant. - The type of data source. If you're using Elasticsearch, the value is
"elasticsearch"
- How many values you want to display. Since a value widget only displays a single value, the
size
is 1. widget
marks the beginning of the widget section as well as the name of the widget. The name doesn't affect the dashboard's function.- Refers to the data source section above which populates it. Make sure the value here matches the name of the corresponding data source exactly. (This is how the widget knows where to get data from.)
- Refers to the field (from the latest log) from which the value will be displayed.
- Title of the widget that will display in the dashboard
- Type of widget. The value type displays a single value.
- See the note above about widget positioning for information about layout lines.
Value widget rendered:
Value widget template:
To create a value widget, copy and paste this template into a dashboard file in the Library and fill in the values. Recommended values as well as the values specifying an Elasicsearch data source are already filled in.
"datasource:Name of datasource": {
"datetimeField": "@timestamp",
"matchPhrase": " ",
"specification": "lmio-{{ tenant }}-events*",
"type": "elasticsearch",
"size": 1
},
"widget:Name of widget": {
"datasource": "datasource:Name of datasource",
"field": " ",
"title": "Widget title",
"type": "Value",
"layout:w": 4,
"layout:h": 1,
"layout:x": 0,
"layout:y": 0,
"layout:moved": false,
"layout:static": true,
"layout:isResizable": false
}
Dashboard example¶
This example is structured correctly:
{
"Prompts": {
"dateRangePicker": true,
"filterInput": true,
"submitButton": true
},
"datasource:access-log-combined HTTP Response": {
"type": "elasticsearch",
"datetimeField": "@timestamp",
"specification": "lmio-default-events*",
"size": 20,
"groupBy": "http.response.status_code",
"matchPhrase": "event.dataset: access-log-combined AND http.response.status_code:*"
},
"widget:access-log-combined HTTP Response": {
"datasource": "datasource:access-log-combined HTTP Response",
"title": "HTTP status codes",
"type": "PieChart",
"color": "warning",
"useGradientColors": true,
"table": true,
"tooltip": true,
"layout:w": 6,
"layout:h": 5,
"layout:x": 6,
"layout:y": 0,
"layout:moved": false,
"layout:static": true,
"layout:isResizable": false
},
"datasource:access-log-combined Activity": {
"type": "elasticsearch",
"datetimeField": "@timestamp",
"specification": "lmio-default-events*",
"matchPhrase": "event.dataset:access-log-combined AND http.response.status_code:*",
"aggregateResult": true
},
"widget:access-log-combined Activity": {
"datasource": "datasource:access-log-combined Activity",
"title": "Activity",
"type": "BarChart",
"table": true,
"xaxis": "@timestamp",
"ylabel": "HTTP requests",
"yaxis": "http.response.status_code",
"color": "sunset",
"layout:w": 6,
"layout:h": 4,
"layout:x": 0,
"layout:y": 1,
"layout:moved": false,
"layout:static": true,
"layout:isResizable": false
},
"datasource:Access-log-combined Last_http": {
"datetimeField": "@timestamp",
"matchPhrase": "event.dataset:access-log-combined AND http.response.status_code:*",
"specification": "lmio-default-events*",
"type": "elasticsearch",
"size": 1000
},
"widget:Access-log-combined Last_http": {
"datasource": "datasource:Access-log-combined Last_http",
"field": "http.response.status_code",
"title": "Last HTTP status code",
"type": "Value",
"layout:w": 6,
"layout:h": 1,
"layout:x": 0,
"layout:y": 0,
"layout:moved": false,
"layout:static": true,
"layout:isResizable": false
}
}
Note: The data is arbitrary. This example is meant only to help you format your dashboards correctly.
Dashboard rendered: