├── src
└── main
│ ├── resources
│ └── webroot
│ │ ├── 404.html
│ │ ├── static
│ │ ├── img
│ │ │ ├── loader.gif
│ │ │ ├── glyphicons-halflings.png
│ │ │ └── glyphicons-halflings-white.png
│ │ ├── bootstrap
│ │ │ ├── fonts
│ │ │ │ ├── glyphicons-halflings-regular.eot
│ │ │ │ ├── glyphicons-halflings-regular.ttf
│ │ │ │ ├── glyphicons-halflings-regular.woff
│ │ │ │ └── glyphicons-halflings-regular.woff2
│ │ │ ├── js
│ │ │ │ ├── npm.js
│ │ │ │ └── bootstrap.min.js
│ │ │ └── css
│ │ │ │ ├── bootstrap-theme.min.css
│ │ │ │ └── bootstrap-theme.css
│ │ ├── templates
│ │ │ ├── http-response-codes.html
│ │ │ ├── threads.html
│ │ │ ├── heap.html
│ │ │ └── logging.html
│ │ ├── css
│ │ │ └── application.css
│ │ └── js
│ │ │ ├── app
│ │ │ ├── vm-information-component.js
│ │ │ ├── logging-component.js
│ │ │ ├── vm-thread-component.js
│ │ │ ├── bindings.js
│ │ │ ├── heap-component.js
│ │ │ ├── application.js
│ │ │ ├── http-error-gauges.js
│ │ │ ├── gc-compartments-component.js
│ │ │ └── http-response-codes-component.js
│ │ │ └── lib
│ │ │ ├── moment.min.js
│ │ │ ├── underscore.min.js
│ │ │ └── jquery.tmpl.js
│ │ └── index.html
│ └── java
│ └── com
│ └── developerb
│ └── dd
│ ├── WebsocketListeners.java
│ ├── DropwizardDashboardStarter.java
│ └── DropwizardClient.java
├── .gitignore
├── screenshots
└── dashboard.png
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── readme.md
├── gradlew.bat
├── gradlew
└── jquery.tmpl.js
/src/main/resources/webroot/404.html:
--------------------------------------------------------------------------------
1 | :-(
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | build
2 | out
3 | .vertx
4 | .gradle
5 | .idea
6 | *.iml
7 | *.ipr
8 | *.iws
9 |
--------------------------------------------------------------------------------
/screenshots/dashboard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kimble/dropwizard-dashboard/HEAD/screenshots/dashboard.png
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kimble/dropwizard-dashboard/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/src/main/resources/webroot/static/img/loader.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kimble/dropwizard-dashboard/HEAD/src/main/resources/webroot/static/img/loader.gif
--------------------------------------------------------------------------------
/src/main/resources/webroot/static/img/glyphicons-halflings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kimble/dropwizard-dashboard/HEAD/src/main/resources/webroot/static/img/glyphicons-halflings.png
--------------------------------------------------------------------------------
/src/main/resources/webroot/static/img/glyphicons-halflings-white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kimble/dropwizard-dashboard/HEAD/src/main/resources/webroot/static/img/glyphicons-halflings-white.png
--------------------------------------------------------------------------------
/src/main/resources/webroot/static/bootstrap/fonts/glyphicons-halflings-regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kimble/dropwizard-dashboard/HEAD/src/main/resources/webroot/static/bootstrap/fonts/glyphicons-halflings-regular.eot
--------------------------------------------------------------------------------
/src/main/resources/webroot/static/bootstrap/fonts/glyphicons-halflings-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kimble/dropwizard-dashboard/HEAD/src/main/resources/webroot/static/bootstrap/fonts/glyphicons-halflings-regular.ttf
--------------------------------------------------------------------------------
/src/main/resources/webroot/static/bootstrap/fonts/glyphicons-halflings-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kimble/dropwizard-dashboard/HEAD/src/main/resources/webroot/static/bootstrap/fonts/glyphicons-halflings-regular.woff
--------------------------------------------------------------------------------
/src/main/resources/webroot/static/bootstrap/fonts/glyphicons-halflings-regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kimble/dropwizard-dashboard/HEAD/src/main/resources/webroot/static/bootstrap/fonts/glyphicons-halflings-regular.woff2
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Sep 11 20:11:25 CEST 2015
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.6-bin.zip
7 |
--------------------------------------------------------------------------------
/src/main/resources/webroot/static/templates/http-response-codes.html:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 | Total responses:
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/main/resources/webroot/static/bootstrap/js/npm.js:
--------------------------------------------------------------------------------
1 | // This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment.
2 | require('../../js/transition.js')
3 | require('../../js/alert.js')
4 | require('../../js/button.js')
5 | require('../../js/carousel.js')
6 | require('../../js/collapse.js')
7 | require('../../js/dropdown.js')
8 | require('../../js/modal.js')
9 | require('../../js/tooltip.js')
10 | require('../../js/popover.js')
11 | require('../../js/scrollspy.js')
12 | require('../../js/tab.js')
13 | require('../../js/affix.js')
--------------------------------------------------------------------------------
/src/main/resources/webroot/static/templates/threads.html:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 | There are a total number of threads
8 | inside the virtual machine.
9 |
10 |
11 |
12 | A daemon thread is a thread, that does not prevent the JVM from exiting when the program finishes but
13 | the thread is still running.
14 | An example for a daemon thread is the garbage collection.
15 |
16 | There are currently daemon threads running inside the JVM.
17 |
18 |
--------------------------------------------------------------------------------
/src/main/resources/webroot/static/css/application.css:
--------------------------------------------------------------------------------
1 |
2 | body {
3 | padding-top: 60px;
4 | padding-bottom: 40px;
5 | }
6 |
7 | .app-header {
8 | border-radius: 3px;
9 | background-color: #555;
10 | color: white;
11 | margin-top: 2em;
12 | }
13 |
14 | .app-header .table {
15 | margin-top: 1em;
16 | }
17 |
18 | .app-header h1 {
19 | font-family: "Arial Black", sans-serif;
20 | }
21 |
22 | .app-header .table td {
23 | border-radius: 3px;
24 | cursor: default;
25 | font-family: "Ubuntu Mono", monospace;
26 | }
27 |
28 | .app-header .table tr:hover {
29 | color: #333;
30 | }
31 |
32 | p.info {
33 | font-size: 1.1em;
34 | font-style: italic;
35 | }
36 |
37 | div.page-header {
38 | margin-top: 4em;
39 | }
40 |
41 | .hiddenFromStart {
42 | visibility: hidden;
43 | }
44 |
45 | .table tr:first-child * {
46 | border-top: 0;
47 | }
48 |
49 | div.hero-unit {
50 | padding: 30px;
51 | }
52 |
53 | footer {
54 | text-align: right;
55 | }
56 |
57 | footer a {
58 | color: #222;
59 | }
60 |
61 | footer a:hover {
62 | text-decoration: none;
63 | }
--------------------------------------------------------------------------------
/src/main/resources/webroot/static/js/app/vm-information-component.js:
--------------------------------------------------------------------------------
1 | (function() {
2 |
3 | function InfoBindings() {
4 | var self = this;
5 |
6 | self.vminfo = ko.observable({
7 | name : 'Unknown',
8 | time : new Date(0),
9 | uptime : 0
10 | });
11 |
12 | self.readableVmUptime = ko.computed(function() {
13 | var uptime = self.vminfo().uptime;
14 | return moment.humanizeDuration(uptime);
15 | });
16 |
17 | self.readableServerTime = ko.computed(function() {
18 | var serverTime = self.vminfo().time;
19 | return moment(serverTime).format("Do MMMM YYYY HH:mm:ss");
20 | });
21 | }
22 |
23 | var bindings = new InfoBindings;
24 |
25 | Dropwizard.registerComponent({
26 | bindings : bindings,
27 |
28 | onMetrics : function(metrics) {
29 | var g = metrics.gauges;
30 |
31 | bindings.vminfo({
32 | name : g['jvm.attribute.vendor'].value,
33 | time : new Date(),
34 | uptime : g['jvm.attribute.uptime'].value
35 | });
36 | }
37 | });
38 |
39 | })();
--------------------------------------------------------------------------------
/src/main/resources/webroot/static/templates/heap.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Initial represents the initial amount of memory and committed represents the amount of memory guaranteed to be available for use by the JVM.
4 | - Reference
5 |
6 |
7 |
8 |
9 |
10 | | Initial: |
11 | |
12 |
13 | Committed: |
14 | |
15 |
16 |
17 | | Used: |
18 | |
19 |
20 | Maximum: |
21 | |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src/main/resources/webroot/static/templates/logging.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | | Trace: |
6 | |
7 |
8 | Info: |
9 | |
10 |
11 |
12 | | Error: |
13 | |
14 |
15 | Warning: |
16 | |
17 |
18 |
19 | | Debug: |
20 | |
21 |
22 | Combined: |
23 | |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | Statistics gathered from log statements written to Logback.
32 |
33 |
34 |
35 | There are currently being written about log messages per second.
36 |
37 |
--------------------------------------------------------------------------------
/src/main/java/com/developerb/dd/WebsocketListeners.java:
--------------------------------------------------------------------------------
1 | package com.developerb.dd;
2 |
3 | import com.fasterxml.jackson.databind.JsonNode;
4 | import com.fasterxml.jackson.databind.ObjectMapper;
5 | import com.fasterxml.jackson.databind.node.ObjectNode;
6 | import io.vertx.core.http.ServerWebSocket;
7 | import io.vertx.core.logging.Logger;
8 | import io.vertx.core.logging.LoggerFactory;
9 |
10 | import java.util.Set;
11 | import java.util.concurrent.CopyOnWriteArraySet;
12 |
13 | /**
14 | * Keeps track of listening browsers
15 | *
16 | * @author Kim A. Betti
17 | */
18 | public class WebsocketListeners {
19 |
20 | private static final Logger log = LoggerFactory.getLogger(WebsocketListeners.class);
21 |
22 | private final Set sockets = new CopyOnWriteArraySet<>();
23 | private final ObjectMapper jackson = new ObjectMapper();
24 |
25 | public void push(String topic, JsonNode json) {
26 | ObjectNode response = jackson.createObjectNode();
27 | response.put("namespace", topic);
28 | response.set("payload", json);
29 |
30 | distribute(response.toString());
31 | }
32 |
33 | public void distribute(final String message) {
34 | for (ServerWebSocket socket : sockets) {
35 | try {
36 | socket.writeFinalTextFrame(message);
37 | }
38 | catch (Exception ex) {
39 | log.warn("Failed to send message to " + socket, ex);
40 | }
41 | }
42 | }
43 |
44 | public void addListener(ServerWebSocket socket) {
45 | log.info("Accepted websocket connection: " + socket);
46 | sockets.add(socket);
47 | }
48 |
49 | public void removeListener(ServerWebSocket socket) {
50 | log.info("Lost websocket connection: " + socket);
51 | sockets.remove(socket);
52 | }
53 |
54 | public boolean hasAtLeastOneListener() {
55 | return !sockets.isEmpty();
56 | }
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | Vertx experiment - Real time Dropwizard dashboard
2 | =======================================
3 |
4 | This was just a weekend experiment to refresh my Javascript knowledge and try out some technologies I've been looking at for some time.
5 | Don't expect it to be of production quality or that I'll maintain it.
6 |
7 | Dropwizard is a well instrumented and productive framework for building production ready restful web services. It exports a lot of statistics on a admin port. I thought it would be fun to create a proxy polling this endpoint and feeding the data to clients connected via web sockets. The proxy is implemented using the fairly new Vertx framework enabling highly concurrent polygot application development on the JVM.
8 |
9 | While I was working on the client side of the dashboard I thought it would be fun to have a look at Knockout.js for data binding. I quite liked the declarative way it solves a lot of common problems related to data binding.
10 |
11 | Latest update
12 | ---------------
13 | Started upgrading Vertx and Bootstrap to their latest versions.
14 |
15 |
16 | Screenshots
17 | ------------
18 | 
19 |
20 |
21 | Give it a spin
22 | --------------
23 |
24 | Fire up a Dropwizard project with the admin interface running on port 8081.
25 |
26 | When Dropwizard is running it should only be a matter of running `./gradlew run` and point your browser to http://localhost:9000/.
27 |
28 | _Ps! This will download and install Gradle in your home folder!_
29 |
30 |
31 | Relevant technologies and libraries
32 | -------------------------------------
33 | http://vertx.io/
34 |
35 | http://dropwizard.codahale.com/
36 |
37 | http://knockoutjs.com/
38 |
39 | http://momentjs.com/
40 |
41 | http://smoothiecharts.org/
42 |
43 | https://developers.google.com/chart/
44 |
45 |
46 |
47 | Things to do
48 | -------------
49 |
50 | **Ditch Knockout:** It does not bring much to the table for this application. Just accidental complexity.
51 |
52 | **Introduce tabs:** The dashboard is too long. Perhaps it would be a good idea to introduce tabs + a small page with a quick overview.
53 |
54 |
55 | Contributions
56 | --------------
57 |
58 | Big thanks to [Daniel Mayo](https://github.com/dmayo3) for his contributions! This was just an evening project and I'd never thought that anyone would pick it up.
59 |
60 | -------------------
61 | [](http://coderwall.com/kimble)
--------------------------------------------------------------------------------
/src/main/resources/webroot/static/js/app/logging-component.js:
--------------------------------------------------------------------------------
1 | (function() {
2 |
3 | var component = {
4 | name : "Logging",
5 | shortDescription : "Application logging statistics",
6 | dom_id : "application_logging_container"
7 | };
8 |
9 |
10 | var bindings = {
11 | applicationLogging : ko.observable({}),
12 |
13 | applicationLoggingAll : ko.observable({}),
14 | applicationLoggingTrace : ko.observable({}),
15 | applicationLoggingInfo : ko.observable({}),
16 | applicationLoggingWarn : ko.observable({}),
17 | applicationLoggingError : ko.observable({}),
18 | applicationLoggingDebug : ko.observable({})
19 | };
20 |
21 | var updateLogging = function(logging) {
22 | console.log("Updating logging")
23 | };
24 |
25 | Dropwizard.registerComponent({
26 | bindings : bindings,
27 | pageComponent : component,
28 |
29 | onMetrics : function(update) {
30 | var logging = update.meters;
31 | bindings.applicationLoggingAll({
32 | count : logging["ch.qos.logback.core.Appender.all"].count,
33 | m1 : roundNumber(logging["ch.qos.logback.core.Appender.all"].m1_rate, 2)
34 | });
35 |
36 | bindings.applicationLoggingTrace({
37 | count : logging["ch.qos.logback.core.Appender.trace"].count
38 | });
39 |
40 | bindings.applicationLoggingInfo({
41 | count : logging["ch.qos.logback.core.Appender.info"].count
42 | });
43 |
44 | bindings.applicationLoggingWarn({
45 | count : logging["ch.qos.logback.core.Appender.warn"].count
46 | });
47 |
48 | bindings.applicationLoggingError({
49 | count : logging["ch.qos.logback.core.Appender.error"].count
50 | });
51 |
52 | bindings.applicationLoggingDebug({
53 | count : logging["ch.qos.logback.core.Appender.debug"].count
54 | });
55 | },
56 |
57 | /**
58 | * Download and install the heap page component template and install it to
59 | * activate Knockout.js data binding.
60 | */
61 | beforeSocketConnect : function() {
62 | Dropwizard.installRemoteTemplate("logging-template", "/static/templates/logging.html");
63 | Dropwizard.appendTemplateTo("logging-template", document.getElementById(component.dom_id));
64 |
65 | bindings.applicationLogging.subscribe(updateLogging);
66 | }
67 | });
68 |
69 | function roundNumber(num, dec) {
70 | return Math.round(num*Math.pow(10,dec))/Math.pow(10,dec);
71 | }
72 |
73 | })();
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/src/main/resources/webroot/static/js/app/vm-thread-component.js:
--------------------------------------------------------------------------------
1 | (function() {
2 |
3 | var options = {
4 | "pieHole": 0.4,
5 | "is3D": false,
6 |
7 | "width": 400,
8 | "height": 200,
9 |
10 | "chartArea": {
11 | left: 10, top: 10,
12 | width: "80%", height: "90%"
13 | },
14 |
15 | "legend": {
16 | position: "right",
17 | textStyle : {
18 | fontSize : 13
19 | }
20 | },
21 |
22 | backgroundColor : {
23 | fill : "transparent"
24 | }
25 | };
26 |
27 | var component = {
28 | name : "Threads",
29 | shortDescription : "Virtual machine threads",
30 | dom_id : "jvm_threads_container"
31 | };
32 |
33 | var bindings = {
34 | virtualMachineThreads : ko.observable({})
35 | };
36 |
37 | var pieChart;
38 |
39 | Dropwizard.registerComponent({
40 | bindings : bindings,
41 | pageComponent : component,
42 |
43 | onMetrics : function(update) {
44 | bindings.virtualMachineThreads({
45 | states : update.gauges,
46 | count : update.gauges["jvm.threads.count"].value,
47 | daemons : update.gauges["jvm.threads.daemon.count"].value,
48 | time: new Date()
49 | });
50 | },
51 |
52 | /**
53 | * Download and install the heap page component template and install it to
54 | * activate Knockout.js data binding.
55 | */
56 | beforeSocketConnect : function() {
57 | Dropwizard.installRemoteTemplate("thread-template", "/static/templates/threads.html");
58 | Dropwizard.appendTemplateTo("thread-template", document.getElementById(component.dom_id));
59 |
60 | var container = document.getElementById("jvm_thread_state_container");
61 | pieChart = new google.visualization.PieChart(container);
62 |
63 | bindings.virtualMachineThreads.subscribe(function(threads) {
64 | var data = [
65 | ["Label", "Value"]
66 | ];
67 |
68 | for (var state in threads.states) {
69 | if (state.match(/jvm\.threads\..*\.count/g)) {
70 | var value = threads.states[state].value;
71 | state = prettyPrintString(state);
72 | data.push([ state, Math.round(value) ]);
73 | }
74 | }
75 |
76 | var plot = google.visualization.arrayToDataTable(data);
77 | pieChart.draw(plot, options);
78 | });
79 | }
80 | });
81 |
82 | function prettyPrintString(string) {
83 | string = string.slice(12);
84 | string = string.substring(0,string.length-5);
85 | return string.charAt(0).toUpperCase() + string.slice(1);
86 | }
87 |
88 | })();
--------------------------------------------------------------------------------
/src/main/resources/webroot/static/js/app/bindings.js:
--------------------------------------------------------------------------------
1 | (function() {
2 |
3 | var defaultBindings = {
4 | googleChartsLoaded : ko.observable(false),
5 | connectionToProxyEstablished : ko.observable(false),
6 | connectionToProxyLost : ko.observable(false),
7 | connectionError : ko.observable(),
8 |
9 | proxyConnectionToDropwizardLost : ko.observable(false),
10 | proxyConnectionToDropwizardRestored : ko.observable(false),
11 |
12 | beforeSocketConnect : ko.observable(),
13 |
14 | healthCheckFailed: ko.observable(false),
15 |
16 | pageComponents : ko.observableArray(),
17 | metrics : ko.observable()
18 | };
19 |
20 | var initializerContext = {
21 | bindings : defaultBindings
22 | };
23 |
24 | Dropwizard = {
25 |
26 | registerComponent : function(component) {
27 | for (var bindingName in component.bindings) {
28 | defaultBindings[bindingName] = component.bindings[bindingName];
29 | }
30 |
31 | if (component.hasOwnProperty("pageComponent")) {
32 | var pageComponent = component.pageComponent;
33 | defaultBindings.pageComponents.push(pageComponent);
34 | }
35 |
36 | if (component.hasOwnProperty("onMetrics")) {
37 | defaultBindings.metrics.subscribe(component.onMetrics);
38 | }
39 |
40 | if (component.hasOwnProperty("onDropwizardConnectionLost")) {
41 | defaultBindings.proxyConnectionToDropwizardLost.subscribe(component.onDropwizardConnectionLost);
42 | }
43 |
44 | if (component.hasOwnProperty("onDropwizardConnectionRestored")) {
45 | defaultBindings.proxyConnectionToDropwizardRestored.subscribe(component.onDropwizardConnectionRestored);
46 | }
47 |
48 | if (component.hasOwnProperty("beforeSocketConnect")) {
49 | defaultBindings.beforeSocketConnect.subscribe(component.beforeSocketConnect);
50 | }
51 | },
52 |
53 | bindings : defaultBindings,
54 |
55 | applyBindings : function() {
56 | ko.applyBindings(defaultBindings);
57 | },
58 |
59 | onMetrics : function(update) {
60 | this.bindings.metrics(update);
61 | },
62 |
63 | installRemoteTemplate : function(id, url) {
64 | jQuery.ajax({
65 | url: url,
66 | async: false,
67 | success: function(template) {
68 | $("body").append("
31 |
32 |
33 |
34 |
35 |
36 |
37 |
64 |
65 |
66 |
67 | Lost connection to proxy - Refresh page to reconnect
68 |
69 |
70 |
71 | Warning! Server healthcheck failed.
72 |
73 |
74 |
75 |
76 |
79 |
80 |
81 |
82 |
89 |
90 |
91 |
92 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |