Compare commits

...

8 Commits

Author SHA1 Message Date
Jon Chambers
aa2f9e5a65 Accept start/end timestamps as milliseconds since the epoch 2025-11-26 09:00:54 -05:00
Jonathan Klabunde Tomer
f13837d2f2 improve OpenTelemetry logging 2025-11-25 12:23:00 -08:00
Jonathan Klabunde Tomer
3ff2af47cb Revert "support JSON logging and prefer it in sample config"
This reverts commit 4d5cc4dc22.
2025-11-25 12:23:00 -08:00
Jon Chambers
c719da3527 Update to the latest version of the spam filter 2025-11-25 12:22:38 -05:00
Jon Chambers
0ea52b785e Update to the latest version of the spam filter 2025-11-25 11:27:05 -05:00
Jon Chambers
1ce1c298d3 Add hooks so spam filters can register Dropwizard commands 2025-11-25 11:07:57 -05:00
Jonathan Klabunde Tomer
4d5cc4dc22 support JSON logging and prefer it in sample config
We won't actually remove OTLP logging support until testing side-by-side and
seeing that things look good.
2025-11-24 16:05:28 -08:00
Jon Chambers
640274108e Make CommandDependencies public 2025-11-24 10:47:00 -05:00
9 changed files with 32 additions and 13 deletions

View File

@@ -355,6 +355,12 @@ public class WhisperServerService extends Application<WhisperServerConfiguration
new IdleDeviceNotificationSchedulerFactory()));
bootstrap.addCommand(new RegenerateSecondaryDynamoDbTableDataCommand());
ServiceLoader.load(SpamFilter.class)
.stream()
.map(ServiceLoader.Provider::get)
.flatMap(spamFilter -> spamFilter.getCommands().stream())
.forEach(bootstrap::addCommand);
}
@Override

View File

@@ -55,8 +55,9 @@ public class CallQualitySurveyManager {
.setResponseId(UUID.randomUUID().toString())
.setSubmissionTimestamp(clock.millis() * 1000)
.setUserSatisfied(submitCallQualitySurveyRequest.getUserSatisfied())
.setStartTimestamp(submitCallQualitySurveyRequest.getStartTimestamp())
.setEndTimestamp(submitCallQualitySurveyRequest.getEndTimestamp())
// We receive timestamps as milliseconds since the epoch, but the backing data store wants microseconds
.setStartTimestamp(submitCallQualitySurveyRequest.getStartTimestamp() * 1_000)
.setEndTimestamp(submitCallQualitySurveyRequest.getEndTimestamp() * 1_000)
.setCallType(submitCallQualitySurveyRequest.getCallType())
.setSuccess(submitCallQualitySurveyRequest.getSuccess())
.setCallEndReason(submitCallQualitySurveyRequest.getCallEndReason());

View File

@@ -30,6 +30,8 @@ import io.opentelemetry.sdk.resources.ResourceBuilder;
import java.time.Duration;
import java.util.Map;
import java.util.Optional;
import org.eclipse.jetty.util.component.LifeCycle;
import org.whispersystems.textsecuregcm.WhisperServerConfiguration;
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicConfiguration;
import org.whispersystems.textsecuregcm.storage.DynamicConfigurationManager;
@@ -120,10 +122,10 @@ public class MetricsUtil {
OpenTelemetryAppender.install(openTelemetry);
environment.lifecycle().manage(new Managed() {
environment.lifecycle().addEventListener(new LifeCycle.Listener() {
@Override
public void stop() {
openTelemetry.shutdown();
public void lifeCycleStopped(final LifeCycle event) {
openTelemetry.close();
}
});
}

View File

@@ -33,6 +33,7 @@ public class OpenTelemetryAppenderFactory extends AbstractAppenderFactory<ILoggi
final OpenTelemetryAppender appender = new OpenTelemetryAppender();
appender.setCaptureCodeAttributes(true);
appender.setCaptureLoggerContext(true);
appender.setCaptureMarkerAttribute(true);
// The installation of an OpenTelemetry configuration happens in
// WhisperServerService (or CommandDependencies), in order to let us tie

View File

@@ -6,10 +6,13 @@
package org.whispersystems.textsecuregcm.spam;
import io.dropwizard.configuration.ConfigurationValidationException;
import io.dropwizard.core.cli.ConfiguredCommand;
import io.dropwizard.lifecycle.Managed;
import jakarta.validation.Validator;
import java.io.IOException;
import java.util.Collection;
import java.util.function.Function;
import org.whispersystems.textsecuregcm.WhisperServerConfiguration;
import org.whispersystems.textsecuregcm.captcha.CaptchaClient;
import org.whispersystems.textsecuregcm.storage.ReportedMessageListener;
@@ -35,6 +38,14 @@ public interface SpamFilter extends Managed {
*/
void configure(String environmentName, Validator validator) throws IOException, ConfigurationValidationException;
/**
* Returns a collection of commands provided by this spam filter. Note that this method may be called before
* {@link #configure(String, Validator)}.
*
* @return a collection of commands provided by this spam filter
*/
Collection<ConfiguredCommand<WhisperServerConfiguration>> getCommands();
/**
* Return a reported message listener controlled by the spam filter. Listeners will be registered with the
* {@link org.whispersystems.textsecuregcm.storage.ReportMessageManager}.

View File

@@ -91,7 +91,7 @@ import software.amazon.awssdk.services.s3.S3AsyncClient;
/**
* Construct utilities commonly used by worker commands
*/
record CommandDependencies(
public record CommandDependencies(
AccountsManager accountsManager,
ProfilesManager profilesManager,
ReportMessageManager reportMessageManager,

View File

@@ -36,12 +36,10 @@ message SubmitCallQualitySurveyRequest {
// to submit debug logs
optional string debug_log_url = 4;
// The time at which the call started in microseconds since the epoch (see
// https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#timestamp_type)
// The time at which the call started in milliseconds since the epoch
int64 start_timestamp = 5;
// The time at which the call ended in microseconds since the epoch (see
// https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#timestamp_type)
// The time at which the call ended in milliseconds since the epoch
int64 end_timestamp = 6;
// The type of call; note that direct voice calls can become video calls and

View File

@@ -122,8 +122,8 @@ class CallQualitySurveyManagerTest {
assertEquals(List.of("too_hot", "too_cold"), callQualitySurveyResponsePubSubMessage.getCallQualityIssuesList());
assertEquals("But this one is just right", callQualitySurveyResponsePubSubMessage.getAdditionalIssuesDescription());
assertEquals("https://example.com/", callQualitySurveyResponsePubSubMessage.getDebugLogUrl());
assertEquals(123456789, callQualitySurveyResponsePubSubMessage.getStartTimestamp());
assertEquals(987654321, callQualitySurveyResponsePubSubMessage.getEndTimestamp());
assertEquals(123456789L * 1_000, callQualitySurveyResponsePubSubMessage.getStartTimestamp());
assertEquals(987654321L * 1_000, callQualitySurveyResponsePubSubMessage.getEndTimestamp());
assertEquals("direct_video", callQualitySurveyResponsePubSubMessage.getCallType());
assertTrue(callQualitySurveyResponsePubSubMessage.getSuccess());
assertEquals("caller_hang_up", callQualitySurveyResponsePubSubMessage.getCallEndReason());