Skip to content

Commit f1ac11d

Browse files
committed
Improve notifier Spring support
- Add Spring boot example app. - Add Spring boot web based example app. - Add `close` method to Bugsnag to ensure it tears down connections (this is automatically called by Spring when tearing down the bean). - Change the simple example to use `close` rather than `Shutdown`.
1 parent 93aba0e commit f1ac11d

20 files changed

Lines changed: 457 additions & 4 deletions

File tree

examples/simple/src/main/java/com/bugsnag/example/simple/ExampleApp.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import java.util.Date;
77

88
public class ExampleApp {
9-
public static void main(String[] args) {
9+
public static void main(String[] args) throws InterruptedException {
1010
// Create a Bugsnag client
1111
Bugsnag bugsnag = new Bugsnag("YOUR-API-KEY");
1212

@@ -55,11 +55,16 @@ public static void main(String[] args) {
5555

5656
// Test an unhanded exception from a different thread as shutdown hooks
5757
// won't be called if executed from this thread
58-
(new Thread() {
58+
Thread thread = new Thread() {
5959
@Override
6060
public void run() {
6161
throw new RuntimeException("Unhandled exception");
6262
}
63-
}).start();
63+
};
64+
65+
thread.start();
66+
67+
// Wait for unhandled exception thread to finish before exiting
68+
thread.join();
6469
}
6570
}

examples/spring-web/README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Bugsnag Spring web Java Example
2+
3+
A Spring Boot example application to show how to use Bugsnag in a Spring web based Java application.
4+
5+
- Start the web server
6+
7+
```shell
8+
../../gradlew clean bootRun
9+
```
10+
11+
- Cause a crash
12+
13+
http://localhost:8080/

examples/spring-web/build.gradle

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
apply plugin: 'spring-boot'
2+
3+
buildscript {
4+
ext {
5+
springBootVersion = '1.4.1.RELEASE'
6+
}
7+
repositories {
8+
jcenter()
9+
}
10+
dependencies {
11+
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
12+
}
13+
}
14+
15+
repositories {
16+
jcenter()
17+
}
18+
19+
dependencies {
20+
compile("org.springframework.boot:spring-boot-starter-web")
21+
22+
compile rootProject
23+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.bugsnag.example.spring.web;
2+
3+
import org.apache.log4j.Logger;
4+
import org.springframework.boot.SpringApplication;
5+
import org.springframework.boot.autoconfigure.SpringBootApplication;
6+
7+
/**
8+
* Kicks off the Spring Boot application.
9+
*/
10+
@SpringBootApplication
11+
public class Application {
12+
13+
private static final Logger LOGGER = Logger.getLogger(Application.class);
14+
15+
public static void main(String[] args) throws Exception {
16+
SpringApplication.run(Application.class, args);
17+
18+
LOGGER.info("Now visit http://localhost:8080 in your web browser");
19+
}
20+
}
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
package com.bugsnag.example.spring.web;
2+
3+
import com.bugsnag.Bugsnag;
4+
import com.bugsnag.Severity;
5+
import org.apache.log4j.Logger;
6+
import org.springframework.beans.factory.annotation.Autowired;
7+
import org.springframework.boot.SpringApplication;
8+
import org.springframework.context.ApplicationContext;
9+
import org.springframework.web.bind.annotation.RequestMapping;
10+
import org.springframework.web.bind.annotation.RestController;
11+
12+
@RestController
13+
public class ApplicationRestController {
14+
15+
private static final Logger LOGGER = Logger.getLogger(ApplicationRestController.class);
16+
17+
// Inject the bugsnag notifier bean defined in Config.java
18+
@Autowired
19+
private Bugsnag bugsnag;
20+
21+
@Autowired
22+
private ApplicationContext applicationContext;
23+
24+
private final String links =
25+
"<a href=\"/send-handled-exception\">Send a handled exception to Bugsnag</a><br/>"
26+
+ "<a href=\"/send-handled-exception-info\">Send a handled exception to Bugsnag with INFO severity</a><br/>"
27+
+ "<a href=\"/send-handled-exception-with-metadata\">Send a handled exception to Bugsnag with custom MetaData</a><br/>"
28+
+ "<a href=\"/send-unhandled-exception\">Send an unhandled exception to Bugsnag</a><br/>"
29+
+ "<a href=\"/shutdown\">Shutdown the application</a><br/>";
30+
31+
@RequestMapping("/")
32+
public String index() {
33+
return links;
34+
}
35+
36+
@RequestMapping("/send-handled-exception")
37+
public String sendHandledException() {
38+
LOGGER.info("Sending a handled exception to Bugsnag");
39+
try {
40+
throw new RuntimeException("Handled exception - default severity");
41+
} catch (RuntimeException e) {
42+
bugsnag.notify(e);
43+
}
44+
45+
return links + "<br/>Sent a handled exception to Bugsnag";
46+
}
47+
48+
@RequestMapping("/send-handled-exception-info")
49+
public String sendHandledExceptionInfo() {
50+
LOGGER.info("Sending a handled exception to Bugsnag with INFO severity");
51+
try {
52+
throw new RuntimeException("Handled exception - INFO severity");
53+
} catch (RuntimeException e) {
54+
bugsnag.notify(e, Severity.INFO);
55+
}
56+
57+
return links + "<br/>Sent a handled exception to Bugsnag with INFO severity";
58+
}
59+
60+
@RequestMapping("/send-handled-exception-with-metadata")
61+
public String sendHandledExceptionWithMetadata() {
62+
LOGGER.info("Sending a handled exception to Bugsnag with custom MetaData");
63+
try {
64+
throw new RuntimeException("Handled exception - custom metadata");
65+
} catch (RuntimeException e) {
66+
bugsnag.notify(e, (report) -> {
67+
report.setSeverity(Severity.WARNING);
68+
report.addToTab("report", "something", "that happened");
69+
report.setContext("the context");
70+
});
71+
}
72+
73+
return links + "<br/>Sent a handled exception to Bugsnag with custom MetaData";
74+
}
75+
76+
@RequestMapping("/send-unhandled-exception")
77+
public String sendUnhandledException() throws InterruptedException {
78+
// Test an unhanded exception from a different thread as shutdown hooks
79+
// won't be called if executed from this thread
80+
LOGGER.info("Sending an unhandled exception to Bugsnag");
81+
Thread thread = new Thread() {
82+
@Override
83+
public void run() {
84+
throw new RuntimeException("Unhandled exception");
85+
}
86+
};
87+
88+
thread.start();
89+
90+
// Wait for unhandled exception thread to finish
91+
thread.join();
92+
93+
return links + "<br/>Sent an unhandled exception to Bugsnag";
94+
}
95+
96+
@RequestMapping("/shutdown")
97+
public void shutdown() throws InterruptedException {
98+
LOGGER.info("Shutting down application");
99+
100+
SpringApplication.exit(applicationContext);
101+
}
102+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package com.bugsnag.example.spring.web;
2+
3+
import com.bugsnag.Bugsnag;
4+
import org.springframework.context.annotation.Bean;
5+
import org.springframework.context.annotation.Configuration;
6+
7+
import java.util.Date;
8+
9+
@Configuration
10+
public class Config {
11+
12+
// Define singleton bean "bugsnag" which can be injected into any Spring managed class with @Autowired.
13+
@Bean
14+
public Bugsnag bugsnag() {
15+
// Create a Bugsnag client
16+
Bugsnag bugsnag = new Bugsnag("YOUR-API-KEY");
17+
18+
// Set some diagnostic data which will not change during the
19+
// lifecycle of the application
20+
bugsnag.setReleaseStage("staging");
21+
bugsnag.setAppVersion("1.0.1");
22+
23+
// Create and attach a simple Bugsnag callback.
24+
// Use Callbacks to send custom diagnostic data which changes during
25+
// the lifecyle of your application
26+
bugsnag.addCallback((report) -> {
27+
report.addToTab("diagnostics", "timestamp", new Date());
28+
report.addToTab("customer", "name", "acme-inc");
29+
report.addToTab("customer", "paying", true);
30+
report.addToTab("customer", "spent", 1234);
31+
report.setUserName("User Name");
32+
report.setUserEmail("[email protected]");
33+
report.setUserId("12345");
34+
});
35+
36+
return bugsnag;
37+
}
38+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
logging.level.com.bugsnag=DEBUG

examples/spring/README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Bugsnag Spring Java Example
2+
3+
A Spring Boot example application to show how to use Bugsnag in a Spring based Java application.
4+
5+
- Run the app
6+
7+
```shell
8+
../../gradlew clean bootRun
9+
```

examples/spring/build.gradle

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
apply plugin: 'spring-boot'
2+
3+
buildscript {
4+
ext {
5+
springBootVersion = '1.4.1.RELEASE'
6+
}
7+
repositories {
8+
jcenter()
9+
}
10+
dependencies {
11+
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
12+
}
13+
}
14+
15+
repositories {
16+
jcenter()
17+
}
18+
19+
dependencies {
20+
compile("org.springframework.boot:spring-boot-starter")
21+
22+
compile rootProject
23+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.bugsnag.example.spring.cli;
2+
3+
import org.springframework.boot.SpringApplication;
4+
import org.springframework.boot.autoconfigure.SpringBootApplication;
5+
6+
/**
7+
* Kicks off the Spring Boot application.
8+
*/
9+
@SpringBootApplication
10+
public class Application {
11+
12+
public static void main(String[] args) throws Exception {
13+
SpringApplication.run(Application.class, args);
14+
}
15+
}

0 commit comments

Comments
 (0)