From e92dea78ebad3f921c031a974378a218c6bd90b1 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 9 Jun 2024 13:37:45 -0700 Subject: Decode text data in logs (fix #5336) --- src/main/java/org/traccar/config/Keys.java | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/main/java/org/traccar/config/Keys.java') diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 91d5dac5d..e51ba07c4 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -1901,6 +1901,14 @@ public final class Keys { List.of(KeyType.CONFIG), true); + /** + * If all bytes are printable characters, log network data as text instead of HEX. + */ + public static final ConfigKey LOGGER_TEXT_PROTOCOL = new BooleanConfigKey( + "logger.decodeTextData", + List.of(KeyType.CONFIG), + true); + /** * Log file rotation interval, the default rotation interval is once a day. * This option is ignored if 'logger.rotate' = false -- cgit v1.2.3 From 690f734e423a6ebe55b3bef5b7ac42cc734b664f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 24 Jun 2024 07:53:42 -0700 Subject: Health check for stored messages --- src/main/java/org/traccar/config/Keys.java | 9 ++++++ .../org/traccar/database/StatisticsManager.java | 4 +++ .../java/org/traccar/schedule/TaskHealthCheck.java | 34 +++++++++++++++++++--- 3 files changed, 43 insertions(+), 4 deletions(-) (limited to 'src/main/java/org/traccar/config/Keys.java') diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index e51ba07c4..ac2adca8a 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -1810,6 +1810,15 @@ public final class Keys { "web.disableHealthCheck", List.of(KeyType.CONFIG)); + /** + * If this parameter is set, Traccar will monitor drops in the number of stored messages. If it drops more than + * the threshold, it will mark service as failing for systemd. Threshold is a value from 0.0 to 1.0. For example, + * value 0.7 means that the number of messages in the last period is only 70% of what it was in the previous. + */ + public static final ConfigKey WEB_HEALTH_CHECK_DROP_THRESHOLD = new DoubleConfigKey( + "web.healthCheck.dropThreshold", + List.of(KeyType.CONFIG)); + /** * Sets SameSite cookie attribute value. * Supported options: Lax, Strict, None. diff --git a/src/main/java/org/traccar/database/StatisticsManager.java b/src/main/java/org/traccar/database/StatisticsManager.java index 8711289a0..d13f72793 100644 --- a/src/main/java/org/traccar/database/StatisticsManager.java +++ b/src/main/java/org/traccar/database/StatisticsManager.java @@ -178,6 +178,10 @@ public class StatisticsManager { } } + public synchronized int messageStoredCount() { + return messagesStored; + } + public synchronized int messageStoredCount(long deviceId) { return deviceMessages.getOrDefault(deviceId, 0); } diff --git a/src/main/java/org/traccar/schedule/TaskHealthCheck.java b/src/main/java/org/traccar/schedule/TaskHealthCheck.java index a60935f18..b3387eca7 100644 --- a/src/main/java/org/traccar/schedule/TaskHealthCheck.java +++ b/src/main/java/org/traccar/schedule/TaskHealthCheck.java @@ -24,6 +24,8 @@ import org.traccar.config.Keys; import jakarta.inject.Inject; import jakarta.ws.rs.client.Client; +import org.traccar.database.StatisticsManager; + import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @@ -33,6 +35,7 @@ public class TaskHealthCheck implements ScheduleTask { private final Config config; private final Client client; + private final StatisticsManager statisticsManager; private final long gracePeriod = System.currentTimeMillis() + TimeUnit.HOURS.toMillis(1); @@ -40,11 +43,16 @@ public class TaskHealthCheck implements ScheduleTask { private boolean enabled; private long period; + private double dropThreshold; + + private int messageLastTotal; + private int messageLastPeriod; @Inject - public TaskHealthCheck(Config config, Client client) { + public TaskHealthCheck(Config config, Client client, StatisticsManager statisticsManager) { this.config = config; this.client = client; + this.statisticsManager = statisticsManager; if (!config.getBoolean(Keys.WEB_DISABLE_HEALTH_CHECK) && System.getProperty("os.name").toLowerCase().startsWith("linux")) { try { @@ -55,6 +63,7 @@ public class TaskHealthCheck implements ScheduleTask { } if (period > 0) { LOGGER.info("Health check enabled with period {}", period); + dropThreshold = config.getDouble(Keys.WEB_HEALTH_CHECK_DROP_THRESHOLD); enabled = true; } } catch (UnsatisfiedLinkError e) { @@ -80,11 +89,28 @@ public class TaskHealthCheck implements ScheduleTask { public void run() { LOGGER.debug("Health check running"); if (System.currentTimeMillis() > gracePeriod) { + boolean success = true; + int status = client.target(getUrl()).request().get().getStatus(); - if (status == 200) { + if (status != 200) { + success = false; + LOGGER.warn("Web health check failed with status {}", status); + } + + if (dropThreshold > 0) { + int messageCurrentTotal = statisticsManager.messageStoredCount(); + int messageCurrentPeriod = messageCurrentTotal - messageLastTotal; + double drop = messageCurrentPeriod / (double) messageLastPeriod; + if (drop < dropThreshold) { + success = false; + LOGGER.warn("Message health check failed with drop {}", drop); + } + messageLastTotal = messageCurrentTotal; + messageLastPeriod = messageCurrentPeriod; + } + + if (success) { notifyWatchdog(); - } else { - LOGGER.warn("Health check failed with status {}", status); } } else { notifyWatchdog(); -- cgit v1.2.3 From 50e9eced4a045c6d1e71abc5203b73da9673abc0 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 13 Jul 2024 14:36:56 -0700 Subject: Some tasks on single server only --- src/main/java/org/traccar/config/Keys.java | 11 +++++++++-- .../java/org/traccar/schedule/ScheduleManager.java | 14 +++++++++++-- .../java/org/traccar/schedule/ScheduleTask.java | 7 ++++++- .../org/traccar/schedule/SingleScheduleTask.java | 23 ++++++++++++++++++++++ .../org/traccar/schedule/TaskDeleteTemporary.java | 2 +- .../schedule/TaskDeviceInactivityCheck.java | 2 +- .../java/org/traccar/schedule/TaskExpirations.java | 2 +- .../java/org/traccar/schedule/TaskReports.java | 2 +- 8 files changed, 54 insertions(+), 9 deletions(-) create mode 100644 src/main/java/org/traccar/schedule/SingleScheduleTask.java (limited to 'src/main/java/org/traccar/config/Keys.java') diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index ac2adca8a..dcd9aaa28 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -1937,8 +1937,8 @@ public final class Keys { "time,position,speed,course,accuracy,result"); /** - * Broadcast method. Available options are "multicast" and "redis". By default (if the value is not - * specified or does not matches available options) server disables broadcast. + * Broadcast method. Available options are "multicast" and "redis". By default, (if the value is not + * specified or does not match available options) server disables broadcast. */ public static final ConfigKey BROADCAST_TYPE = new StringConfigKey( "broadcast.type", @@ -1965,4 +1965,11 @@ public final class Keys { "broadcast.port", List.of(KeyType.CONFIG)); + /** + * Flag to mark secondary servers. Some tasks, like scheduled reports, will be executed on the main server only. + */ + public static final ConfigKey BROADCAST_SECONDARY = new BooleanConfigKey( + "broadcast.secondary", + List.of(KeyType.CONFIG)); + } diff --git a/src/main/java/org/traccar/schedule/ScheduleManager.java b/src/main/java/org/traccar/schedule/ScheduleManager.java index 742428fd8..fd8171148 100644 --- a/src/main/java/org/traccar/schedule/ScheduleManager.java +++ b/src/main/java/org/traccar/schedule/ScheduleManager.java @@ -20,6 +20,9 @@ import org.traccar.LifecycleObject; import jakarta.inject.Inject; import jakarta.inject.Singleton; +import org.traccar.config.Config; +import org.traccar.config.Keys; + import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.stream.Stream; @@ -28,11 +31,13 @@ import java.util.stream.Stream; public class ScheduleManager implements LifecycleObject { private final Injector injector; + private final boolean secondary; private ScheduledExecutorService executor; @Inject - public ScheduleManager(Injector injector) { + public ScheduleManager(Injector injector, Config config) { this.injector = injector; + secondary = config.getBoolean(Keys.BROADCAST_SECONDARY); } @Override @@ -46,7 +51,12 @@ public class ScheduleManager implements LifecycleObject { TaskReports.class, TaskDeviceInactivityCheck.class, TaskWebSocketKeepalive.class) - .forEachOrdered(task -> injector.getInstance(task).schedule(executor)); + .forEachOrdered(taskClass -> { + var task = injector.getInstance(taskClass); + if (task.multipleInstances() || !secondary) { + task.schedule(executor); + } + }); } @Override diff --git a/src/main/java/org/traccar/schedule/ScheduleTask.java b/src/main/java/org/traccar/schedule/ScheduleTask.java index 1b537213b..a2a31ac4f 100644 --- a/src/main/java/org/traccar/schedule/ScheduleTask.java +++ b/src/main/java/org/traccar/schedule/ScheduleTask.java @@ -1,5 +1,5 @@ /* - * Copyright 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2022 - 2024 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,5 +18,10 @@ package org.traccar.schedule; import java.util.concurrent.ScheduledExecutorService; public interface ScheduleTask extends Runnable { + + default boolean multipleInstances() { + return true; + } + void schedule(ScheduledExecutorService executor); } diff --git a/src/main/java/org/traccar/schedule/SingleScheduleTask.java b/src/main/java/org/traccar/schedule/SingleScheduleTask.java new file mode 100644 index 000000000..a0f1deee4 --- /dev/null +++ b/src/main/java/org/traccar/schedule/SingleScheduleTask.java @@ -0,0 +1,23 @@ +/* + * Copyright 2024 Anton Tananaev (anton@traccar.org) + * + * 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.traccar.schedule; + +public abstract class SingleScheduleTask implements ScheduleTask { + @Override + public boolean multipleInstances() { + return false; + } +} diff --git a/src/main/java/org/traccar/schedule/TaskDeleteTemporary.java b/src/main/java/org/traccar/schedule/TaskDeleteTemporary.java index 0cead59fb..eb49b7e46 100644 --- a/src/main/java/org/traccar/schedule/TaskDeleteTemporary.java +++ b/src/main/java/org/traccar/schedule/TaskDeleteTemporary.java @@ -28,7 +28,7 @@ import java.util.Date; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; -public class TaskDeleteTemporary implements ScheduleTask { +public class TaskDeleteTemporary extends SingleScheduleTask { private static final Logger LOGGER = LoggerFactory.getLogger(TaskDeleteTemporary.class); diff --git a/src/main/java/org/traccar/schedule/TaskDeviceInactivityCheck.java b/src/main/java/org/traccar/schedule/TaskDeviceInactivityCheck.java index 8e45568d5..9bc98d8d3 100644 --- a/src/main/java/org/traccar/schedule/TaskDeviceInactivityCheck.java +++ b/src/main/java/org/traccar/schedule/TaskDeviceInactivityCheck.java @@ -34,7 +34,7 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; -public class TaskDeviceInactivityCheck implements ScheduleTask { +public class TaskDeviceInactivityCheck extends SingleScheduleTask { private static final Logger LOGGER = LoggerFactory.getLogger(TaskDeviceInactivityCheck.class); diff --git a/src/main/java/org/traccar/schedule/TaskExpirations.java b/src/main/java/org/traccar/schedule/TaskExpirations.java index e16dcd86c..03be0c97f 100644 --- a/src/main/java/org/traccar/schedule/TaskExpirations.java +++ b/src/main/java/org/traccar/schedule/TaskExpirations.java @@ -36,7 +36,7 @@ import org.traccar.storage.query.Request; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; -public class TaskExpirations implements ScheduleTask { +public class TaskExpirations extends SingleScheduleTask { private static final Logger LOGGER = LoggerFactory.getLogger(TaskExpirations.class); diff --git a/src/main/java/org/traccar/schedule/TaskReports.java b/src/main/java/org/traccar/schedule/TaskReports.java index c57158cb9..1b9b15749 100644 --- a/src/main/java/org/traccar/schedule/TaskReports.java +++ b/src/main/java/org/traccar/schedule/TaskReports.java @@ -50,7 +50,7 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; -public class TaskReports implements ScheduleTask { +public class TaskReports extends SingleScheduleTask { private static final Logger LOGGER = LoggerFactory.getLogger(TaskReports.class); -- cgit v1.2.3