Browse Source

monitoring service improvements: provisioning dashboard, make monitoring asset and dashboard public, log dashboard url, notify on startup and shutdown, shutdown thread pools on PreDestroy, removed file based logback in favour of stdout, logback severity down to INFO, JAVA_OPTS adjusted

pull/14605/head
Sergey Matvienko 10 months ago
parent
commit
4a6177d85e
  1. 20
      monitoring/src/main/conf/logback.xml
  2. 7
      monitoring/src/main/conf/tb-monitoring.conf
  3. 37
      monitoring/src/main/java/org/thingsboard/monitoring/ThingsboardMonitoringApplication.java
  4. 27
      monitoring/src/main/java/org/thingsboard/monitoring/data/notification/InfoNotification.java
  5. 29
      monitoring/src/main/java/org/thingsboard/monitoring/notification/NotificationService.java
  6. 120
      monitoring/src/main/java/org/thingsboard/monitoring/service/MonitoringEntityService.java
  7. 580
      monitoring/src/main/resources/dashboard_cloud_monitoring.json
  8. 3
      monitoring/src/main/resources/logback.xml

20
monitoring/src/main/conf/logback.xml

@ -19,20 +19,6 @@
<!DOCTYPE configuration> <!DOCTYPE configuration>
<configuration scan="true" scanPeriod="30 seconds"> <configuration scan="true" scanPeriod="30 seconds">
<appender name="fileLogAppender"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${pkg.logFolder}/${pkg.name}.log</file>
<rollingPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${pkg.logFolder}/${pkg.name}.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>100MB</maxFileSize>
<maxHistory>30</maxHistory>
<totalSizeCap>3GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%d{ISO8601} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>%d{ISO8601} [%thread] %-5level %logger{36} - %msg%n</pattern> <pattern>%d{ISO8601} [%thread] %-5level %logger{36} - %msg%n</pattern>
@ -40,11 +26,11 @@
</appender> </appender>
<logger name="org" level="WARN"/> <logger name="org" level="WARN"/>
<logger name="org.thingsboard.monitoring" level="DEBUG"/> <logger name="org.thingsboard.server" level="INFO"/>
<logger name="org.thingsboard.monitoring.client" level="INFO"/> <logger name="org.thingsboard.monitoring" level="INFO"/>
<logger name="org.thingsboard.monitoring.client" level="WARN"/>
<root level="INFO"> <root level="INFO">
<appender-ref ref="fileLogAppender"/>
<appender-ref ref="STDOUT"/> <appender-ref ref="STDOUT"/>
</root> </root>

7
monitoring/src/main/conf/tb-monitoring.conf

@ -14,9 +14,10 @@
# limitations under the License. # limitations under the License.
# #
export JAVA_OPTS="$JAVA_OPTS -Xlog:gc*,heap*,age*,safepoint=debug:file=/var/log/tb-monitoring/gc.log:time,uptime,level,tags:filecount=10,filesize=10M" export JAVA_OPTS="$JAVA_OPTS -Xlog:gc*,heap*,age*,safepoint=debug:file=/var/log/tb-monitoring/gc.log:time,uptime,level,tags:filecount=3,filesize=10M"
export JAVA_OPTS="$JAVA_OPTS -XX:+IgnoreUnrecognizedVMOptions -XX:+HeapDumpOnOutOfMemoryError" export JAVA_OPTS="$JAVA_OPTS -XX:+IgnoreUnrecognizedVMOptions -XX:+HeapDumpOnOutOfMemoryError"
export JAVA_OPTS="$JAVA_OPTS -XX:-UseBiasedLocking -XX:+UseTLAB -XX:+ResizeTLAB -XX:+PerfDisableSharedMem -XX:+UseCondCardMark" export JAVA_OPTS="$JAVA_OPTS -XX:+UseTLAB -XX:+ResizeTLAB -XX:+PerfDisableSharedMem -XX:+UseCondCardMark"
export JAVA_OPTS="$JAVA_OPTS -XX:+UseG1GC -XX:MaxGCPauseMillis=500 -XX:+UseStringDeduplication -XX:+ParallelRefProcEnabled -XX:MaxTenuringThreshold=10" export JAVA_OPTS="$JAVA_OPTS -XX:+UseG1GC -XX:MaxGCPauseMillis=50 -XX:+ParallelRefProcEnabled -XX:MaxTenuringThreshold=10"
export JAVA_OPTS="$JAVA_OPTS -XX:+ExitOnOutOfMemoryError"
export LOG_FILENAME=tb-monitoring.out export LOG_FILENAME=tb-monitoring.out
export LOADER_PATH=/usr/share/tb-monitoring/conf export LOADER_PATH=/usr/share/tb-monitoring/conf

37
monitoring/src/main/java/org/thingsboard/monitoring/ThingsboardMonitoringApplication.java

@ -15,36 +15,43 @@
*/ */
package org.thingsboard.monitoring; package org.thingsboard.monitoring;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener; import org.springframework.context.event.EventListener;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.EnableScheduling;
import org.thingsboard.common.util.ThingsBoardExecutors; import org.thingsboard.common.util.ThingsBoardExecutors;
import org.thingsboard.monitoring.data.notification.InfoNotification;
import org.thingsboard.monitoring.notification.NotificationService;
import org.thingsboard.monitoring.service.BaseMonitoringService; import org.thingsboard.monitoring.service.BaseMonitoringService;
import org.thingsboard.monitoring.service.MonitoringEntityService; import org.thingsboard.monitoring.service.MonitoringEntityService;
import jakarta.annotation.PreDestroy;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@SpringBootApplication @SpringBootApplication
@EnableScheduling @EnableScheduling
@Slf4j @Slf4j
@RequiredArgsConstructor
public class ThingsboardMonitoringApplication { public class ThingsboardMonitoringApplication {
@Autowired private final List<BaseMonitoringService<?, ?>> monitoringServices;
private List<BaseMonitoringService<?, ?>> monitoringServices; private final MonitoringEntityService entityService;
@Autowired private final NotificationService notificationService;
private MonitoringEntityService entityService;
@Value("${monitoring.monitoring_rate_ms}") @Value("${monitoring.monitoring_rate_ms}")
private int monitoringRateMs; private int monitoringRateMs;
ScheduledExecutorService scheduler = ThingsBoardExecutors.newSingleThreadScheduledExecutor("monitoring-executor");
public static void main(String[] args) { public static void main(String[] args) {
new SpringApplicationBuilder(ThingsboardMonitoringApplication.class) new SpringApplicationBuilder(ThingsboardMonitoringApplication.class)
.properties(Map.of("spring.config.name", "tb-monitoring")) .properties(Map.of("spring.config.name", "tb-monitoring"))
@ -56,12 +63,30 @@ public class ThingsboardMonitoringApplication {
entityService.checkEntities(); entityService.checkEntities();
monitoringServices.forEach(BaseMonitoringService::init); monitoringServices.forEach(BaseMonitoringService::init);
ScheduledExecutorService scheduler = ThingsBoardExecutors.newSingleThreadScheduledExecutor("monitoring-executor");
scheduler.scheduleWithFixedDelay(() -> { scheduler.scheduleWithFixedDelay(() -> {
monitoringServices.forEach(monitoringService -> { monitoringServices.forEach(monitoringService -> {
monitoringService.runChecks(); monitoringService.runChecks();
}); });
}, 0, monitoringRateMs, TimeUnit.MILLISECONDS); }, 0, monitoringRateMs, TimeUnit.MILLISECONDS);
notificationService.sendNotification(new InfoNotification(":rocket: Monitoring started"));
}
@EventListener(ContextClosedEvent.class)
public void onShutdown(ContextClosedEvent event) {
log.info("Shutting down monitoring service");
try {
var futures = notificationService.sendNotification(new InfoNotification(":warning: Monitoring is shutting down"));
for (Future<?> future : futures) {
future.get(5, TimeUnit.SECONDS);
}
} catch (Exception e) {
log.warn("Failed to send shutdown notification", e);
}
}
@PreDestroy
public void shutdownScheduler() {
scheduler.shutdown();
} }
} }

27
monitoring/src/main/java/org/thingsboard/monitoring/data/notification/InfoNotification.java

@ -0,0 +1,27 @@
/**
* Copyright © 2016-2025 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.monitoring.data.notification;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
public class InfoNotification implements Notification {
private final String message;
@Override
public String getText() {
return message;
}
}

29
monitoring/src/main/java/org/thingsboard/monitoring/notification/NotificationService.java

@ -22,10 +22,13 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.thingsboard.monitoring.data.notification.Notification; import org.thingsboard.monitoring.data.notification.Notification;
import org.thingsboard.monitoring.notification.channels.NotificationChannel; import org.thingsboard.monitoring.notification.channels.NotificationChannel;
import jakarta.annotation.PreDestroy;
import java.util.List; import java.util.List;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
@Component @Component
@RequiredArgsConstructor @RequiredArgsConstructor
@ -38,22 +41,38 @@ public class NotificationService {
@Value("${monitoring.notifications.message_prefix}") @Value("${monitoring.notifications.message_prefix}")
private String messagePrefix; private String messagePrefix;
public void sendNotification(Notification notification) { public List<? extends Future<?>> sendNotification(Notification notification) {
String message; String message;
if (StringUtils.isEmpty(messagePrefix)) { if (StringUtils.isEmpty(messagePrefix)) {
message = notification.getText(); message = notification.getText();
} else { } else {
message = messagePrefix + System.lineSeparator() + notification.getText(); message = messagePrefix + " " + notification.getText();
} }
notificationChannels.forEach(notificationChannel -> { return notificationChannels.stream().map(notificationChannel ->
notificationExecutor.submit(() -> { notificationExecutor.submit(() -> {
try { try {
notificationChannel.sendNotification(message); notificationChannel.sendNotification(message);
} catch (Exception e) { } catch (Exception e) {
log.error("Failed to send notification to {}", notificationChannel.getClass().getSimpleName(), e); log.error("Failed to send notification to {}", notificationChannel.getClass().getSimpleName(), e);
} }
}); })
}); ).toList();
} }
@PreDestroy
public void shutdownExecutor() {
try {
notificationExecutor.shutdown();
if (!notificationExecutor.awaitTermination(10, TimeUnit.SECONDS)) {
java.util.List<Runnable> dropped = notificationExecutor.shutdownNow();
log.warn("Notification executor did not terminate in time. Forced shutdown; {} task(s) will not be executed.", dropped.size());
}
} catch (InterruptedException e) {
java.util.List<Runnable> dropped = notificationExecutor.shutdownNow();
Thread.currentThread().interrupt();
log.warn("Interrupted during notification executor shutdown. Forced shutdown; {} task(s) will not be executed.", dropped.size());
} catch (Exception e) {
log.warn("Unexpected error while shutting down notification executor", e);
}
}
} }

120
monitoring/src/main/java/org/thingsboard/monitoring/service/MonitoringEntityService.java

@ -30,13 +30,19 @@ import org.thingsboard.monitoring.config.transport.TransportMonitoringTarget;
import org.thingsboard.monitoring.config.transport.TransportType; import org.thingsboard.monitoring.config.transport.TransportType;
import org.thingsboard.monitoring.util.ResourceUtils; import org.thingsboard.monitoring.util.ResourceUtils;
import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.Dashboard;
import org.thingsboard.server.common.data.DashboardInfo;
import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.DeviceProfileType; import org.thingsboard.server.common.data.DeviceProfileType;
import org.thingsboard.server.common.data.DeviceTransportType; import org.thingsboard.server.common.data.DeviceTransportType;
import org.thingsboard.server.common.data.ShortCustomerInfo;
import org.thingsboard.server.common.data.TbResource; import org.thingsboard.server.common.data.TbResource;
import org.thingsboard.server.common.data.asset.Asset; import org.thingsboard.server.common.data.asset.Asset;
import org.thingsboard.server.common.data.cf.CalculatedField; import org.thingsboard.server.common.data.cf.CalculatedField;
import org.thingsboard.server.common.data.id.DashboardId;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.cf.CalculatedFieldType; import org.thingsboard.server.common.data.cf.CalculatedFieldType;
import org.thingsboard.server.common.data.cf.configuration.Argument; import org.thingsboard.server.common.data.cf.configuration.Argument;
import org.thingsboard.server.common.data.cf.configuration.ArgumentType; import org.thingsboard.server.common.data.cf.configuration.ArgumentType;
@ -57,7 +63,6 @@ import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileTra
import org.thingsboard.server.common.data.device.profile.DeviceProfileData; import org.thingsboard.server.common.data.device.profile.DeviceProfileData;
import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.kv.KvEntry; import org.thingsboard.server.common.data.kv.KvEntry;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.data.rule.RuleChain;
import org.thingsboard.server.common.data.rule.RuleChainMetaData; import org.thingsboard.server.common.data.rule.RuleChainMetaData;
import org.thingsboard.server.common.data.rule.RuleChainType; import org.thingsboard.server.common.data.rule.RuleChainType;
@ -66,6 +71,8 @@ import org.thingsboard.server.common.data.security.DeviceCredentialsType;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static org.thingsboard.monitoring.service.BaseHealthChecker.TEST_CF_TELEMETRY_KEY; import static org.thingsboard.monitoring.service.BaseHealthChecker.TEST_CF_TELEMETRY_KEY;
@ -76,6 +83,9 @@ import static org.thingsboard.monitoring.service.BaseHealthChecker.TEST_TELEMETR
@RequiredArgsConstructor @RequiredArgsConstructor
public class MonitoringEntityService { public class MonitoringEntityService {
private static final String DASHBOARD_TITLE = "[Monitoring] Cloud monitoring";
private static final String DASHBOARD_RESOURCE_PATH = "dashboard_cloud_monitoring.json";
private final TbClient tbClient; private final TbClient tbClient;
@Value("${monitoring.calculated_fields.enabled:true}") @Value("${monitoring.calculated_fields.enabled:true}")
@ -95,27 +105,34 @@ public class MonitoringEntityService {
int currentVersion = Integer.parseInt(attributes.getOrDefault("version", "0")); int currentVersion = Integer.parseInt(attributes.getOrDefault("version", "0"));
int newVersion = ruleChainDescriptor.get("version").asInt(); int newVersion = ruleChainDescriptor.get("version").asInt();
if (currentVersion == newVersion) { if (currentVersion == newVersion) {
log.info("Not updating rule chain, version is the same ({})", currentVersion); log.debug("Not updating rule chain, version is the same ({})", currentVersion);
return;
} else { } else {
log.info("Updating rule chain '{}' from version {} to {}", ruleChain.getName(), currentVersion, newVersion); log.info("Updating rule chain '{}' from version {} to {}", ruleChain.getName(), currentVersion, newVersion);
String metadataJson = RegexUtils.replace(ruleChainDescriptor.get("metadata").toString(),
"\\$\\{MONITORING:(.+?)}", matchResult -> {
String key = matchResult.group(1);
String value = attributes.get(key);
if (value == null) {
throw new IllegalArgumentException("No attribute found for key " + key);
}
log.info("Using {}: {}", key, value);
return value;
});
RuleChainMetaData metaData = JacksonUtil.fromString(metadataJson, RuleChainMetaData.class);
metaData.setRuleChainId(ruleChainId);
tbClient.saveRuleChainMetaData(metaData);
tbClient.saveEntityAttributesV2(ruleChainId, DataConstants.SERVER_SCOPE, JacksonUtil.newObjectNode()
.put("version", newVersion));
} }
String metadataJson = RegexUtils.replace(ruleChainDescriptor.get("metadata").toString(), Asset asset = getOrCreateMonitoringAsset();
"\\$\\{MONITORING:(.+?)}", matchResult -> { Dashboard dashboard = getOrCreateMonitoringDashboard();
String key = matchResult.group(1);
String value = attributes.get(key); tbClient.assignAssetToPublicCustomer(asset.getId());
if (value == null) { tbClient.assignDashboardToPublicCustomer(dashboard.getId());
throw new IllegalArgumentException("No attribute found for key " + key);
} getDashboardPublicLink(dashboard);
log.info("Using {}: {}", key, value);
return value;
});
RuleChainMetaData metaData = JacksonUtil.fromString(metadataJson, RuleChainMetaData.class);
metaData.setRuleChainId(ruleChainId);
tbClient.saveRuleChainMetaData(metaData);
tbClient.saveEntityAttributesV2(ruleChainId, DataConstants.SERVER_SCOPE, JacksonUtil.newObjectNode()
.put("version", newVersion));
} }
public Asset getOrCreateMonitoringAsset() { public Asset getOrCreateMonitoringAsset() {
@ -249,4 +266,71 @@ public class MonitoringEntityService {
tbClient.saveCalculatedField(calculatedField); tbClient.saveCalculatedField(calculatedField);
} }
private String getDashboardPublicLink(Dashboard dashboard) {
String link = "";
try {
Optional<DashboardInfo> infoOpt = tbClient.getDashboardInfoById(dashboard.getId());
if (infoOpt.isPresent()) {
String publicCustomerId = null;
Set<ShortCustomerInfo> customers = infoOpt.get().getAssignedCustomers();
if (customers != null) {
publicCustomerId = customers.stream()
.filter(ShortCustomerInfo::isPublic)
.map(c -> c.getCustomerId().getId().toString())
.findFirst().orElse(null);
}
if (publicCustomerId != null) {
link = buildPublicDashboardLink(dashboard.getId(), publicCustomerId);
log.info("Public Monitoring dashboard link: {}", link);
} else {
log.warn("Dashboard is not assigned to public customer. Public link can't be generated.");
}
}
} catch (Exception e) {
log.error("Failed to get a public link to Monitoring dashboard ", e);
}
return link;
}
private Dashboard getOrCreateMonitoringDashboard() {
Dashboard existing = findDashboardByTitle(DASHBOARD_TITLE).orElse(null);
if (existing != null) {
log.debug("Found Monitoring dashboard '{}' with id {}", existing.getTitle(), existing.getId());
return existing;
}
Dashboard dashboardFromResource = ResourceUtils.getResource(DASHBOARD_RESOURCE_PATH, Dashboard.class);
dashboardFromResource.setTitle(DASHBOARD_TITLE);
//Optional.ofNullable(existing).map(Dashboard::getId).ifPresent(dashboardFromResource::setId);
Dashboard saved = tbClient.saveDashboard(dashboardFromResource);
log.info("Created Monitoring dashboard '{}' with id {}", saved.getTitle(), saved.getId());
return saved;
}
private Optional<Dashboard> findDashboardByTitle(String title) {
// Use text search first and then filter by exact title
PageData<DashboardInfo> page = tbClient.getTenantDashboards(new PageLink(10, 0, title));
return page.getData().stream()
.filter(info -> title.equals(info.getTitle()))
.findFirst()
.flatMap(info -> tbClient.getDashboardById(info.getId()));
}
private String buildPublicDashboardLink(DashboardId dashboardId, String publicCustomerId) {
String base = getBaseUrl();
return String.format("%s/dashboard/%s?publicId=%s", base, dashboardId.getId().toString(), publicCustomerId);
}
private String getBaseUrl() {
// TbClient.baseURL contains the root url, without trailing slash
try {
var baseUrlField = tbClient.getClass().getSuperclass().getDeclaredField("baseURL");
baseUrlField.setAccessible(true);
return (String) baseUrlField.get(tbClient);
} catch (Exception e) {
log.warn("Unable to access baseURL from RestClient. Falling back to http://localhost:8080");
return "http://localhost:8080";
}
}
} }

580
monitoring/src/main/resources/dashboard_cloud_monitoring.json

@ -0,0 +1,580 @@
{
"title": "Cloud - Monitoring",
"image": null,
"mobileHide": false,
"mobileOrder": null,
"configuration": {
"description": "",
"widgets": {
"7db7f580-2aac-d7ee-20f6-3d9315e7003f": {
"type": "timeseries",
"sizeX": 8,
"sizeY": 5,
"config": {
"datasources": [
{
"type": "entity",
"name": null,
"entityAliasId": "6451461f-d748-9528-e3cd-64078c7fae05",
"filterId": null,
"dataKeys": [
{
"name": "arrivalLatency",
"type": "timeseries",
"label": "Arrival latency",
"color": "#ffc107",
"settings": {},
"_hash": 0.7424467450112592,
"aggregationType": null,
"units": "ms",
"decimals": null,
"funcBody": null,
"usePostProcessing": null,
"postFuncBody": null
},
{
"name": "processingTime",
"type": "timeseries",
"label": "Processing time",
"color": "#607d8b",
"settings": {},
"_hash": 0.6065128737901203,
"aggregationType": null,
"units": "ms",
"decimals": null,
"funcBody": null,
"usePostProcessing": null,
"postFuncBody": null
},
{
"name": "mqttTransportWsUpdateLatency",
"type": "timeseries",
"label": "MQTT - overall",
"color": "#f44336",
"settings": {},
"_hash": 0.19638031054010696,
"aggregationType": null,
"units": "ms",
"decimals": null,
"funcBody": null,
"usePostProcessing": null,
"postFuncBody": null
},
{
"name": "coapTransportWsUpdateLatency",
"type": "timeseries",
"label": "CoAP - overall",
"color": "#9c27b0",
"settings": {},
"_hash": 0.8167481665043521,
"aggregationType": null,
"units": "ms",
"decimals": null,
"funcBody": null,
"usePostProcessing": null,
"postFuncBody": null
},
{
"name": "httpTransportWsUpdateLatency",
"type": "timeseries",
"label": "HTTP - overall",
"color": "#8bc34a",
"settings": {},
"_hash": 0.45369210935861803,
"aggregationType": null,
"units": "ms",
"decimals": null,
"funcBody": null,
"usePostProcessing": null,
"postFuncBody": null
},
{
"name": "lwm2mTransportWsUpdateLatency",
"type": "timeseries",
"label": "LwM2M - overall",
"color": "#3f51b5",
"settings": {},
"_hash": 0.3477627917073993,
"aggregationType": null,
"units": "ms",
"decimals": null,
"funcBody": null,
"usePostProcessing": null,
"postFuncBody": null
},
{
"name": "coapIntegrationWsUpdateLatency",
"type": "timeseries",
"label": "CoAP integration - overall",
"color": "#e91e63",
"settings": {},
"_hash": 0.8332881819050183,
"aggregationType": null,
"units": "ms",
"decimals": null,
"funcBody": null,
"usePostProcessing": null,
"postFuncBody": null
},
{
"name": "wsSubscribeLatency",
"type": "timeseries",
"label": "WS subscribe latency",
"color": "#03a9f4",
"settings": {},
"_hash": 0.7843180730206556,
"aggregationType": null,
"units": "ms",
"decimals": null,
"funcBody": null,
"usePostProcessing": null,
"postFuncBody": null
},
{
"name": "wsConnectLatency",
"type": "timeseries",
"label": "WS connect latency",
"color": "#4caf50",
"settings": {
"hideDataByDefault": false,
"disableDataHiding": false,
"removeFromLegend": false,
"excludeFromStacking": false,
"showLines": true,
"lineWidth": 1,
"fillLines": false,
"showPoints": false,
"tooltipValueFormatter": "",
"showSeparateAxis": false,
"axisTitle": "",
"axisMin": null,
"axisMax": null,
"axisPosition": "left",
"axisTickSize": null,
"axisTickDecimals": null,
"axisTicksFormatter": "",
"comparisonSettings": {
"showValuesForComparison": true,
"comparisonValuesLabel": "",
"color": ""
},
"thresholds": []
},
"_hash": 0.23140687573220564,
"aggregationType": null,
"units": "ms",
"decimals": null,
"funcBody": null,
"usePostProcessing": null,
"postFuncBody": null
},
{
"name": "logInLatency",
"type": "timeseries",
"label": "Log in latency",
"color": "#2196f3",
"settings": {
"hideDataByDefault": false,
"disableDataHiding": false,
"removeFromLegend": false,
"excludeFromStacking": false,
"showLines": true,
"lineWidth": 1,
"fillLines": false,
"showPoints": false,
"tooltipValueFormatter": "",
"showSeparateAxis": false,
"axisTitle": "",
"axisMin": null,
"axisMax": null,
"axisPosition": "left",
"axisTickSize": null,
"axisTickDecimals": null,
"axisTicksFormatter": "",
"comparisonSettings": {
"showValuesForComparison": true,
"comparisonValuesLabel": "",
"color": ""
},
"thresholds": []
},
"_hash": 0.6130919996800452,
"aggregationType": null,
"units": "ms",
"decimals": null,
"funcBody": null,
"usePostProcessing": null,
"postFuncBody": null
}
],
"alarmFilterConfig": {
"statusList": [
"ACTIVE"
]
},
"latestDataKeys": []
}
],
"timewindow": {
"realtime": {
"timewindowMs": 60000
}
},
"showTitle": true,
"backgroundColor": "#fff",
"color": "rgba(0, 0, 0, 0.87)",
"padding": "8px",
"settings": {
"stack": false,
"fontSize": 10,
"fontColor": "#545454",
"showTooltip": true,
"tooltipIndividual": false,
"tooltipCumulative": false,
"hideZeros": false,
"grid": {
"verticalLines": true,
"horizontalLines": true,
"outlineWidth": 1,
"color": "#545454",
"backgroundColor": null,
"tickColor": "#DDDDDD"
},
"xaxis": {
"title": null,
"showLabels": true,
"color": "#545454"
},
"yaxis": {
"min": null,
"max": null,
"title": null,
"showLabels": true,
"color": "#545454",
"tickSize": null,
"tickDecimals": 0,
"ticksFormatter": ""
},
"shadowSize": 4,
"smoothLines": false,
"comparisonEnabled": false,
"timeForComparison": "previousInterval",
"comparisonCustomIntervalValue": 7200000,
"xaxisSecond": {
"axisPosition": "top",
"title": null,
"showLabels": true
},
"customLegendEnabled": false,
"dataKeysListForLabels": [],
"showLegend": true,
"legendConfig": {
"direction": "column",
"position": "bottom",
"sortDataKeys": false,
"showMin": false,
"showMax": true,
"showAvg": true,
"showTotal": false,
"showLatest": true
}
},
"title": "General latencies",
"dropShadow": false,
"enableFullscreen": true,
"titleStyle": {
"fontSize": "16px",
"fontWeight": 400
},
"useDashboardTimewindow": true,
"showTitleIcon": false,
"titleTooltip": "",
"widgetStyle": {},
"widgetCss": "",
"pageSize": 1024,
"noDataDisplayMessage": "",
"enableDataExport": true,
"displayTimewindow": true
},
"row": 0,
"col": 0,
"id": "7db7f580-2aac-d7ee-20f6-3d9315e7003f",
"typeFullFqn": "system.charts.basic_timeseries"
},
"e0a2df43-2f9a-efcf-80f7-bf51b0a174e1": {
"type": "timeseries",
"sizeX": 8,
"sizeY": 5,
"config": {
"datasources": [
{
"type": "entity",
"name": null,
"entityAliasId": "6451461f-d748-9528-e3cd-64078c7fae05",
"filterId": null,
"dataKeys": [
{
"name": "mqttTransportRequestLatency",
"type": "timeseries",
"label": "MQTT transport request latency",
"color": "#2196f3",
"settings": {},
"_hash": 0.8576659620523571,
"aggregationType": null,
"units": "ms",
"decimals": null,
"funcBody": null,
"usePostProcessing": null,
"postFuncBody": null
},
{
"name": "httpTransportRequestLatency",
"type": "timeseries",
"label": "HTTP transport request latency",
"color": "#4caf50",
"settings": {},
"_hash": 0.9749033105491403,
"aggregationType": null,
"units": "ms",
"decimals": null,
"funcBody": null,
"usePostProcessing": null,
"postFuncBody": null
},
{
"name": "coapTransportRequestLatency",
"type": "timeseries",
"label": "CoAP transport request latency",
"color": "#f44336",
"settings": {},
"_hash": 0.6977575200148037,
"aggregationType": null,
"units": "ms",
"decimals": null,
"funcBody": null,
"usePostProcessing": null,
"postFuncBody": null
},
{
"name": "coapIntegrationRequestLatency",
"type": "timeseries",
"label": "CoAP integration request latency",
"color": "#9c27b0",
"settings": {},
"_hash": 0.18839685494200875,
"aggregationType": null,
"units": "ms",
"decimals": null,
"funcBody": null,
"usePostProcessing": null,
"postFuncBody": null
},
{
"name": "lwm2mTransportRequestLatency",
"type": "timeseries",
"label": "LwM2M transport request latency",
"color": "#ffc107",
"settings": {
"hideDataByDefault": false,
"disableDataHiding": false,
"removeFromLegend": false,
"excludeFromStacking": false,
"showLines": true,
"lineWidth": 1,
"fillLines": false,
"showPoints": false,
"tooltipValueFormatter": "",
"showSeparateAxis": false,
"axisTitle": "",
"axisMin": null,
"axisMax": null,
"axisPosition": "left",
"axisTickSize": null,
"axisTickDecimals": null,
"axisTicksFormatter": "",
"comparisonSettings": {
"showValuesForComparison": true,
"comparisonValuesLabel": "",
"color": ""
},
"thresholds": []
},
"_hash": 0.85549409179514,
"aggregationType": null,
"units": "ms",
"decimals": null,
"funcBody": null,
"usePostProcessing": null,
"postFuncBody": null
}
],
"alarmFilterConfig": {
"statusList": [
"ACTIVE"
]
},
"latestDataKeys": []
}
],
"timewindow": {
"realtime": {
"timewindowMs": 60000
}
},
"showTitle": true,
"backgroundColor": "#fff",
"color": "rgba(0, 0, 0, 0.87)",
"padding": "8px",
"settings": {
"shadowSize": 4,
"fontColor": "#545454",
"fontSize": 10,
"xaxis": {
"showLabels": true,
"color": "#545454"
},
"yaxis": {
"showLabels": true,
"color": "#545454"
},
"grid": {
"color": "#545454",
"tickColor": "#DDDDDD",
"verticalLines": true,
"horizontalLines": true,
"outlineWidth": 1
},
"legend": {
"show": true,
"position": "nw",
"backgroundColor": "#f0f0f0",
"backgroundOpacity": 0.85,
"labelBoxBorderColor": "rgba(1, 1, 1, 0.45)"
},
"decimals": 1,
"stack": false,
"tooltipIndividual": false,
"showLegend": true,
"legendConfig": {
"direction": "column",
"position": "bottom",
"sortDataKeys": false,
"showMin": false,
"showMax": true,
"showAvg": true,
"showTotal": false,
"showLatest": true
}
},
"title": "Transport latencies",
"dropShadow": false,
"enableFullscreen": true,
"titleStyle": {
"fontSize": "16px",
"fontWeight": 400
},
"useDashboardTimewindow": true,
"showTitleIcon": false,
"titleTooltip": "",
"widgetStyle": {},
"widgetCss": "",
"pageSize": 1024,
"noDataDisplayMessage": "",
"enableDataExport": true,
"displayTimewindow": true
},
"row": 0,
"col": 0,
"id": "e0a2df43-2f9a-efcf-80f7-bf51b0a174e1",
"typeFullFqn": "system.charts.basic_timeseries"
}
},
"states": {
"default": {
"name": "Cloud - Monitoring",
"root": true,
"layouts": {
"main": {
"widgets": {
"7db7f580-2aac-d7ee-20f6-3d9315e7003f": {
"sizeX": 12,
"sizeY": 11,
"row": 0,
"col": 0
},
"e0a2df43-2f9a-efcf-80f7-bf51b0a174e1": {
"sizeX": 12,
"sizeY": 11,
"row": 0,
"col": 12
}
},
"gridSettings": {
"backgroundColor": "#eeeeee",
"columns": 24,
"margin": 10,
"backgroundSizeMode": "100%",
"outerMargin": true,
"layoutType": "default"
}
}
}
}
},
"entityAliases": {
"6451461f-d748-9528-e3cd-64078c7fae05": {
"id": "6451461f-d748-9528-e3cd-64078c7fae05",
"alias": "Monitoring stats asset",
"filter": {
"type": "entityName",
"resolveMultiple": true,
"entityType": "ASSET",
"entityNameFilter": "[Monitoring] Latencies"
}
}
},
"filters": {},
"timewindow": {
"hideAggregation": false,
"hideAggInterval": false,
"hideTimezone": false,
"selectedTab": 0,
"realtime": {
"realtimeType": 0,
"interval": 120000,
"timewindowMs": 18000000,
"quickInterval": "CURRENT_DAY",
"hideInterval": false,
"hideLastInterval": false,
"hideQuickInterval": false
},
"history": {
"historyType": 0,
"interval": 600000,
"timewindowMs": 43200000,
"fixedTimewindow": null,
"quickInterval": "CURRENT_DAY",
"hideInterval": false,
"hideLastInterval": false,
"hideFixedInterval": false,
"hideQuickInterval": false
},
"aggregation": {
"type": "AVG",
"limit": 2500
},
"timezone": null
},
"settings": {
"stateControllerId": "entity",
"showTitle": false,
"showDashboardsSelect": true,
"showEntitiesSelect": true,
"showDashboardTimewindow": true,
"showDashboardExport": true,
"toolbarAlwaysOpen": true
}
},
"name": "Cloud - Monitoring",
"resources": null
}

3
monitoring/src/main/resources/logback.xml

@ -17,7 +17,7 @@
--> -->
<!DOCTYPE configuration> <!DOCTYPE configuration>
<configuration scan="true" scanPeriod="10 seconds"> <configuration scan="true" scanPeriod="30 seconds">
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
@ -34,5 +34,4 @@
<appender-ref ref="STDOUT"/> <appender-ref ref="STDOUT"/>
</root> </root>
</configuration> </configuration>

Loading…
Cancel
Save