Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sentry configuration #36

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.smartregister.fhir.gateway;

import org.smartregister.fhir.gateway.plugins.SentryConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
Expand All @@ -9,11 +10,16 @@
* plugins defined in "com.google.fhir.gateway.plugin" and "org.smartregister.fhir.gateway.plugins.
*/
@SpringBootApplication(
scanBasePackages = {"org.smartregister.fhir.gateway", "com.google.fhir.gateway.plugin"})
scanBasePackages = {
"org.smartregister.fhir.gateway",
"com.google.fhir.gateway.plugin",
"org.smartregister.fhir.gateway.plugins"
})
@ServletComponentScan({"org.smartregister.fhir.gateway.plugins", "com.google.fhir.gateway"})
public class MainApp {

public static void main(String[] args) {
SentryConfiguration.initialize();
SpringApplication.run(MainApp.class, args);
}
}
5 changes: 5 additions & 0 deletions plugins/application.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
sentry:
dsn: ""
release:
environment: ""
enabled: true
22 changes: 22 additions & 0 deletions plugins/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,28 @@
<version>1.0.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>2.2.0.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
<version>2.1.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.sentry</groupId>
<artifactId>sentry-logback</artifactId>
<version>7.3.0</version>
</dependency>

</dependencies>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package org.smartregister.fhir.gateway.plugins;

import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;

import com.google.common.annotations.VisibleForTesting;

import io.sentry.Sentry;
import io.sentry.SentryOptions;
import jakarta.annotation.PostConstruct;

@ConditionalOnProperty(
prefix = "sentry",
name = "enabled",
havingValue = "true",
matchIfMissing = false)
@Configuration
public class SentryConfiguration {

static final Logger logger = LoggerFactory.getLogger(SentryConfiguration.class);

private static String dsn;

private static String release;
private static String environment;
private static Map<String, String> tags;
private static boolean debug;

@Value("${sentry.dsn:}")
public void setDsn(String dsn) {
SentryConfiguration.dsn = dsn;
}

@Value("${sentry.release:}")
public void setRelease(String release) {
SentryConfiguration.release = release;
}

@Value("${sentry.environment:}")
public void setEnvironment(String environment) {
SentryConfiguration.environment = environment;
}

@Value("#{${sentry.tags: {}} ?: {}}")
public void setTags(Map<String, String> tags) {
SentryConfiguration.tags = tags;
}

@Value("${sentry.debug: false}")
public void setDebug(boolean debug) {
SentryConfiguration.debug = debug;
}

@PostConstruct
public static void initialize() {
if (dsn != null && !dsn.trim().isEmpty()) {
initializeSentry();
}
}

@VisibleForTesting
public static void initializeSentry() {
Sentry.init(
sentryOptions -> {
sentryOptions.setDsn(dsn);
sentryOptions.setRelease(release);
sentryOptions.setEnvironment(environment);
sentryOptions.setDebug(debug);
populateTags(sentryOptions);
});
}

@VisibleForTesting
public static void populateTags(SentryOptions sentryOptions) {
try {
for (Map.Entry<String, String> extraTagsEntry : tags.entrySet()) {
String key = extraTagsEntry.getKey();
if (key != null && !key.trim().isEmpty())
sentryOptions.setTag(extraTagsEntry.getKey(), extraTagsEntry.getValue());
}
} catch (Exception e) {
logger.error(e.getMessage());
}
}
}
14 changes: 14 additions & 0 deletions plugins/src/main/resources/logback.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<configuration>
<appender name="Sentry" class="io.sentry.logback.SentryAppender">
<!-- Optionally change minimum Event level. Default for Events is ERROR -->
<minimumEventLevel>ERROR</minimumEventLevel>
<!-- Optionally change minimum Breadcrumbs level. Default for Breadcrumbs is INFO -->
<minimumBreadcrumbLevel>INFO</minimumBreadcrumbLevel>
</appender>

<!-- Enable the Console and Sentry appenders, Console is provided as an example
of a non-Sentry logger that is set to a different logging threshold -->
<root level="INFO">
<appender-ref ref="Sentry" />
</root>
</configuration>
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package org.smartregister.fhir.gateway.plugins;

import static org.mockito.Mockito.*;

import java.util.HashMap;
import java.util.Map;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.reflect.internal.WhiteboxImpl;

import io.sentry.Sentry;
import io.sentry.SentryOptions;

@RunWith(PowerMockRunner.class)
@PrepareForTest(Sentry.class)
public class SentryConfigurationTest {

private SentryConfiguration sentryConfiguration;

@Before
public void setUp() {
sentryConfiguration = spy(new SentryConfiguration());
}

@Test
public void testInitializeShouldNotInitializeSentryIfDsnIsEmpty() {
WhiteboxImpl.setInternalState(sentryConfiguration, "dsn", "");
sentryConfiguration.initialize();
verify(sentryConfiguration, never()).initializeSentry();
}

@Test
public void testInitializeShouldInitializeSentryIfDsnIsNotEmpty() {
PowerMockito.mockStatic(Sentry.class);
WhiteboxImpl.setInternalState(
sentryConfiguration, "dsn", "https://examplePublicKey.sdsd.w/0");
sentryConfiguration.initialize();
verify(sentryConfiguration, atMost(1)).initializeSentry();
}

@Test
public void testPopulateTagsShouldNotAddTagsIfNotPresent() {
WhiteboxImpl.setInternalState(sentryConfiguration, "tags", new HashMap<>());
SentryOptions sentryOptions = mock(SentryOptions.class);
sentryConfiguration.populateTags(sentryOptions);
verify(sentryOptions, never()).setTag(anyString(), anyString());
}

@Test
public void testPopulateTagsShouldAddTagsToSentryOptions() {
String releaseName = "release-name";
String release = "release-a";
Map<String, String> map = new HashMap<>();
map.put(releaseName, release);
WhiteboxImpl.setInternalState(sentryConfiguration, "tags", map);
SentryOptions sentryOptions = mock(SentryOptions.class);
sentryConfiguration.populateTags(sentryOptions);
verify(sentryOptions, only()).setTag(eq(releaseName), eq(release));
}
}
Loading