Repository: jhipster/generator-jhipster
Pull request #9010 (2019-01-04 12:18:25)

 Fixing #8944
3 characters PR (what an achievement !), I guess still good for a first one.


Patch:
diff --git a/generators/cleanup.js b/generators/cleanup.js
index 579ad72237..7e5b1dd216 100644
--- a/generators/cleanup.js
+++ b/generators/cleanup.js
@@ -70,11 +70,6 @@ function cleanupOldFiles(generator) {
         generator.removeFile(`${CLIENT_TEST_SRC_DIR}spec/entry.ts`);
         generator.removeFile(`${CLIENT_TEST_SRC_DIR}karma.conf.js`);
     }
-    if (generator.isJhipsterVersionLessThan('5.8.0')) {
-        generator.removeFile(`${ANGULAR_DIR}admin/metrics/metrics-modal.component.html`);
-        generator.removeFile(`${ANGULAR_DIR}admin/metrics/metrics-modal.component.ts`);
-        generator.removeFile(`${CLIENT_TEST_SRC_DIR}spec/app/admin/metrics/metrics-modal.component.spec.ts`);
-    }
 }
 
 /**
@@ -170,7 +165,6 @@ function cleanupOldServerFiles(generator, javaDir, testDir, mainResourceDir, tes
         }
     }
     if (generator.isJhipsterVersionLessThan('5.8.0')) {
-        generator.removeFile(`${javaDir}config/MetricsConfiguration.java`);
         if (generator.databaseType === 'cassandra') {
             generator.removeFile(`${testResourceDir}cassandra-random-port.yml`);
         }
diff --git a/generators/client/files-angular.js b/generators/client/files-angular.js
index 61cf6f5bc6..0f6cace8f4 100644
--- a/generators/client/files-angular.js
+++ b/generators/client/files-angular.js
@@ -278,6 +278,8 @@ const files = {
                 { file: 'admin/metrics/metrics.route.ts', method: 'processJs' },
                 { file: 'admin/metrics/metrics.component.ts', method: 'processJs' },
                 { file: 'admin/metrics/metrics.component.html', method: 'processHtml', template: true },
+                'admin/metrics/metrics-modal.component.ts',
+                { file: 'admin/metrics/metrics-modal.component.html', method: 'processHtml', template: true },
                 'admin/metrics/metrics.service.ts'
             ]
         },
@@ -433,6 +435,7 @@ const files = {
                 'spec/app/admin/logs/logs.service.spec.ts',
                 'spec/app/admin/metrics/metrics.component.spec.ts',
                 'spec/app/admin/metrics/metrics.service.spec.ts',
+                'spec/app/admin/metrics/metrics-modal.component.spec.ts',
                 'spec/app/core/user/account.service.spec.ts',
                 'spec/helpers/spyobject.ts',
                 'spec/helpers/mock-account.service.ts',
diff --git a/generators/client/files-react.js b/generators/client/files-react.js
index 6a6617a999..813ff7bbb7 100644
--- a/generators/client/files-react.js
+++ b/generators/client/files-react.js
@@ -261,6 +261,8 @@ const files = {
                 { file: 'modules/administration/health/health-modal.tsx', method: 'processJsx' },
                 { file: 'modules/administration/logs/logs.tsx', method: 'processJsx' },
                 { file: 'modules/administration/metrics/metrics.tsx', method: 'processJsx' },
+                { file: 'modules/administration/metrics/metrics-modal.tsx', method: 'processJsx' },
+                { file: 'modules/administration/metrics/thread-item.tsx', method: 'processJsx' },
                 'modules/administration/administration.reducer.ts'
             ]
         },
diff --git a/generators/client/templates/angular/package.json.ejs b/generators/client/templates/angular/package.json.ejs
index 09f059c6a3..14996a34f1 100644
--- a/generators/client/templates/angular/package.json.ejs
+++ b/generators/client/templates/angular/package.json.ejs
@@ -41,7 +41,7 @@
     "bootstrap": "4.1.3",
     "core-js": "2.5.7",
     "moment": "2.22.2",
-    "ng-jhipster": "0.6.0",
+    "ng-jhipster": "0.5.6",
     "ngx-cookie": "2.0.1",
     "ngx-infinite-scroll": "6.0.1",
     "ngx-webstorage": "2.0.1",
diff --git a/generators/client/templates/angular/src/main/webapp/app/admin/admin.module.ts.ejs b/generators/client/templates/angular/src/main/webapp/app/admin/admin.module.ts.ejs
index 70569653e7..b1c4650775 100644
--- a/generators/client/templates/angular/src/main/webapp/app/admin/admin.module.ts.ejs
+++ b/generators/client/templates/angular/src/main/webapp/app/admin/admin.module.ts.ejs
@@ -37,6 +37,7 @@ import {
     UserMgmtDeleteDialogComponent,
     <%_ } _%>
     LogsComponent,
+    <%=jhiPrefixCapitalized%>MetricsMonitoringModalComponent,
     <%=jhiPrefixCapitalized%>MetricsMonitoringComponent,
     <%=jhiPrefixCapitalized%>HealthModalComponent,
     <%=jhiPrefixCapitalized%>HealthCheckComponent,
@@ -77,7 +78,8 @@ import {
         <%_ if (websocket === 'spring-websocket') { _%>
         <%=jhiPrefixCapitalized%>TrackerComponent,
         <%_ } _%>
-        <%=jhiPrefixCapitalized%>MetricsMonitoringComponent
+        <%=jhiPrefixCapitalized%>MetricsMonitoringComponent,
+        <%=jhiPrefixCapitalized%>MetricsMonitoringModalComponent
     ],
     <%_ if (enableTranslation) { _%>
     providers: [ { provide: JhiLanguageService, useClass: JhiLanguageService } ],
@@ -86,7 +88,8 @@ import {
         <%_ if (!skipUserManagement) { _%>
         UserMgmtDeleteDialogComponent,
         <%_ } _%>
-        <%=jhiPrefixCapitalized%>HealthModalComponent
+        <%=jhiPrefixCapitalized%>HealthModalComponent,
+        <%=jhiPrefixCapitalized%>MetricsMonitoringModalComponent,
     ],
     schemas: [CUSTOM_ELEMENTS_SCHEMA]
 })
diff --git a/generators/client/templates/angular/src/main/webapp/app/admin/index.ts.ejs b/generators/client/templates/angular/src/main/webapp/app/admin/index.ts.ejs
index 95e7667f4a..69f4d8920b 100644
--- a/generators/client/templates/angular/src/main/webapp/app/admin/index.ts.ejs
+++ b/generators/client/templates/angular/src/main/webapp/app/admin/index.ts.ejs
@@ -47,6 +47,7 @@ export * from './tracker/tracker.component';
 export * from './tracker/tracker.route';
 <%_ } _%>
 export * from './metrics/metrics.component';
+export * from './metrics/metrics-modal.component';
 export * from './metrics/metrics.service';
 export * from './metrics/metrics.route';
 <%_ if (!skipUserManagement) { _%>
diff --git a/generators/client/templates/angular/src/main/webapp/app/admin/metrics/metrics.component.html.ejs b/generators/client/templates/angular/src/main/webapp/app/admin/metrics/metrics.component.html.ejs
index 6e3575c6a6..6a912da4cb 100644
--- a/generators/client/templates/angular/src/main/webapp/app/admin/metrics/metrics.component.html.ejs
+++ b/generators/client/templates/angular/src/main/webapp/app/admin/metrics/metrics.component.html.ejs
@@ -26,22 +26,248 @@
 
     <h3 jhiTranslate="metrics.jvm.title">JVM Metrics</h3>
     <div class="row" *ngIf="!updatingMetrics">
-        <jhi-jvm-memory class="col-md-4" [updating]="updatingMetrics" [jvmMemoryMetrics]="metrics.jvm"></jhi-jvm-memory>
-        <jhi-jvm-threads class="col-md-4" [threadData]="threadData"></jhi-jvm-threads>
-        <jhi-metrics-system class="col-md-4" [updating]="updatingMetrics" [systemMetrics]="metrics.processMetrics"></jhi-metrics-system>
+        <div class="col-md-4">
+            <b jhiTranslate="metrics.jvm.memory.title">Memory</b>
+            <p><span jhiTranslate="metrics.jvm.memory.total">Total Memory</span> ({{metrics.gauges['jvm.memory.total.used'].value / 1048576 | number:'1.0-0'}}M / {{metrics.gauges['jvm.memory.total.max'].value / 1048576 | number:'1.0-0'}}M)</p>
+            <ngb-progressbar type="success" [max]="metrics.gauges['jvm.memory.total.max'].value" [value]="metrics.gauges['jvm.memory.total.used'].value" [striped]="true" [animated]="false">
+                <span>{{metrics.gauges['jvm.memory.total.used'].value * 100 / metrics.gauges['jvm.memory.total.max'].value  | number:'1.0-0'}}%</span>
+            </ngb-progressbar>
+            <p><span jhiTranslate="metrics.jvm.memory.heap">Heap Memory</span> ({{metrics.gauges['jvm.memory.heap.used'].value / 1048576 | number:'1.0-0'}}M / {{metrics.gauges['jvm.memory.heap.max'].value / 1048576 | number:'1.0-0'}}M)</p>
+            <ngb-progressbar [max]="metrics.gauges['jvm.memory.heap.max'].value" [value]="metrics.gauges['jvm.memory.heap.used'].value" [striped]="true" [animated]="false" type="success">
+                <span>{{metrics.gauges['jvm.memory.heap.used'].value * 100 / metrics.gauges['jvm.memory.heap.max'].value  | number:'1.0-0'}}%</span>
+            </ngb-progressbar>
+            <p><span jhiTranslate="metrics.jvm.memory.nonheap">Non-Heap Memory</span> ({{metrics.gauges['jvm.memory.non-heap.used'].value / 1048576 | number:'1.0-0'}}M / {{metrics.gauges['jvm.memory.non-heap.committed'].value / 1048576 | number:'1.0-0'}}M)</p>
+            <ngb-progressbar [max]="metrics.gauges['jvm.memory.non-heap.committed'].value" [value]="metrics.gauges['jvm.memory.non-heap.used'].value" [striped]="true" [animated]="false" type="success">
+                <span>{{metrics.gauges['jvm.memory.non-heap.used'].value * 100 / metrics.gauges['jvm.memory.non-heap.committed'].value  | number:'1.0-0'}}%</span>
+            </ngb-progressbar>
+        </div>
+        <div class="col-md-4">
+            <b jhiTranslate="metrics.jvm.threads.title">Threads</b> (Total: {{metrics.gauges['jvm.threads.count'].value}}) <a class="hand" (click)="refreshThreadDumpData()" data-toggle="modal" data-target="#threadDump"><fa-icon [icon]="'eye'"></fa-icon></a>
+            <p><span jhiTranslate="metrics.jvm.threads.runnable">Runnable</span> {{metrics.gauges['jvm.threads.runnable.count'].value}}</p>
+            <ngb-progressbar [value]="metrics.gauges['jvm.threads.runnable.count'].value" [max]="metrics.gauges['jvm.threads.count'].value" [striped]="true" [animated]="false" type="success">
+                <span>{{metrics.gauges['jvm.threads.runnable.count'].value * 100 / metrics.gauges['jvm.threads.count'].value  | number:'1.0-0'}}%</span>
+            </ngb-progressbar>
+            <p><span jhiTranslate="metrics.jvm.threads.timedwaiting">Timed Waiting</span> ({{metrics.gauges['jvm.threads.timed_waiting.count'].value}})</p>
+            <ngb-progressbar [value]="metrics.gauges['jvm.threads.timed_waiting.count'].value" [max]="metrics.gauges['jvm.threads.count'].value" [striped]="true" [animated]="false" type="warning">
+                <span>{{metrics.gauges['jvm.threads.timed_waiting.count'].value * 100 / metrics.gauges['jvm.threads.count'].value  | number:'1.0-0'}}%</span>
+            </ngb-progressbar>
+            <p><span jhiTranslate="metrics.jvm.threads.waiting">Waiting</span> ({{metrics.gauges['jvm.threads.waiting.count'].value}})</p>
+            <ngb-progressbar [value]="metrics.gauges['jvm.threads.waiting.count'].value" [max]="metrics.gauges['jvm.threads.count'].value" [striped]="true" [animated]="false" type="warning">
+                <span>{{metrics.gauges['jvm.threads.waiting.count'].value * 100 / metrics.gauges['jvm.threads.count'].value  | number:'1.0-0'}}%</span>
+            </ngb-progressbar>
+            <p><span jhiTranslate="metrics.jvm.threads.blocked">Blocked</span> ({{metrics.gauges['jvm.threads.blocked.count'].value}})</p>
+            <ngb-progressbar [value]="metrics.gauges['jvm.threads.blocked.count'].value" [max]="metrics.gauges['jvm.threads.count'].value" [striped]="true" [animated]="false" type="success">
+                <span>{{metrics.gauges['jvm.threads.blocked.count'].value * 100 / metrics.gauges['jvm.threads.count'].value  | number:'1.0-0'}}%</span>
+            </ngb-progressbar>
+        </div>
+        <div class="col-md-4">
+            <b jhiTranslate="metrics.jvm.gc.title">Garbage collections</b>
+            <div class="row" *ngIf="metrics.gauges['jvm.garbage.PS-MarkSweep.count']">
+                <div class="col-md-9" jhiTranslate="metrics.jvm.gc.marksweepcount">Mark Sweep count</div>
+                <div class="col-md-3 text-right">{{metrics.gauges['jvm.garbage.PS-MarkSweep.count'].value}}</div>
+            </div>
+            <div class="row" *ngIf="metrics.gauges['jvm.garbage.PS-MarkSweep.time']">
+                <div class="col-md-9" jhiTranslate="metrics.jvm.gc.marksweeptime">Mark Sweep time</div>
+                <div class="col-md-3 text-right">{{metrics.gauges['jvm.garbage.PS-MarkSweep.time'].value}}ms</div>
+            </div>
+            <div class="row" *ngIf="metrics.gauges['jvm.garbage.PS-Scavenge.count']">
+                <div class="col-md-9" jhiTranslate="metrics.jvm.gc.scavengecount">Scavenge count</div>
+                <div class="col-md-3 text-right">{{metrics.gauges['jvm.garbage.PS-Scavenge.count'].value}}</div>
+            </div>
+            <div class="row" *ngIf="metrics.gauges['jvm.garbage.PS-Scavenge.time']">
+                <div class="col-md-9" jhiTranslate="metrics.jvm.gc.scavengetime">Scavenge time</div>
+                <div class="col-md-3 text-right">{{metrics.gauges['jvm.garbage.PS-Scavenge.time'].value}}ms</div>
+            </div>
+        </div>
     </div>
-
-    <h3 jhiTranslate="metrics.jvm.gc.title">Garbage collector statistics</h3>
-    <jhi-metrics-garbagecollector [updating]="updatingMetrics" [garbageCollectorMetrics]="metrics.garbageCollector"></jhi-metrics-garbagecollector>
-
     <div class="well well-lg" *ngIf="updatingMetrics" jhiTranslate="metrics.updating">Updating...</div>
 
-    <jhi-metrics-request [updating]="updatingMetrics" [requestMetrics]="metrics['http.server.requests']"></jhi-metrics-request>
-
-    <jhi-metrics-endpoints-requests [updating]="updatingMetrics" [endpointsRequestsMetrics]="metrics.endpointsRequests"></jhi-metrics-endpoints-requests>
-
-    <jhi-metrics-cache [updating]="updatingMetrics" [cacheMetrics]="metrics.cache"></jhi-metrics-cache>
-
-    <jhi-metrics-datasource [updating]="updatingMetrics" [datasourceMetrics]="metrics.databases"></jhi-metrics-datasource>
+    <h3 jhiTranslate="metrics.jvm.http.title">HTTP requests (events per second)</h3>
+    <p *ngIf="metrics.counters">
+        <span jhiTranslate="metrics.jvm.http.active">Active requests</span> <b>{{metrics.counters['com.codahale.metrics.servlet.InstrumentedFilter.activeRequests'].count | number:'1.0-0'}}</b> - <span jhiTranslate="metrics.jvm.http.total">Total requests</span> <b>{{metrics.timers['com.codahale.metrics.servlet.InstrumentedFilter.requests'].count | number:'1.0-0'}}</b>
+    </p>
+    <div class="table-responsive" *ngIf="!updatingMetrics">
+        <table class="table table-striped">
+            <thead>
+            <tr>
+                <th jhiTranslate="metrics.jvm.http.table.code">Code</th>
+                <th jhiTranslate="metrics.jvm.http.table.count">Count</th>
+                <th class="text-right" jhiTranslate="metrics.jvm.http.table.mean">Mean</th>
+                <th class="text-right"><span jhiTranslate="metrics.jvm.http.table.average">Average</span> (1 min)</th>
+                <th class="text-right"><span jhiTranslate="metrics.jvm.http.table.average">Average</span> (5 min)</th>
+                <th class="text-right"><span jhiTranslate="metrics.jvm.http.table.average">Average</span> (15 min)</th>
+            </tr>
+            </thead>
+            <tbody>
+            <tr>
+                <td jhiTranslate="metrics.jvm.http.code.ok">OK</td>
+                <td>
+                    <ngb-progressbar [max]="metrics.timers['com.codahale.metrics.servlet.InstrumentedFilter.requests'].count" [value]="metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.ok'].count" [striped]="true" [animated]="false" type="success">
+                        <span>{{metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.ok'].count}}</span>
+                    </ngb-progressbar>
+                </td>
+                <td class="text-right">
+                    {{filterNaN(metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.ok'].mean_rate) | number:'1.0-2'}}
+                </td>
+                <td class="text-right">
+                    {{filterNaN(metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.ok'].m1_rate) | number:'1.0-2'}}
+                </td>
+                <td class="text-right">
+                    {{filterNaN(metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.ok'].m5_rate) | number:'1.0-2'}}
+                </td>
+                <td class="text-right">
+                    {{filterNaN(metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.ok'].m15_rate) | number:'1.0-2'}}
+                </td>
+            </tr>
+            <tr>
+                <td jhiTranslate="metrics.jvm.http.code.notfound">Not Found</td>
+                <td>
+                    <ngb-progressbar [max]="metrics.timers['com.codahale.metrics.servlet.InstrumentedFilter.requests'].count" [value]="metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.notFound'].count" [striped]="true" [animated]="false" type="success">
+                        <span>{{metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.notFound'].count}}</span>
+                    </ngb-progressbar>
+                </td>
+                <td class="text-right">
+                    {{filterNaN(metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.notFound'].mean_rate) | number:'1.0-2'}}
+                </td>
+                <td class="text-right">
+                    {{filterNaN(metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.notFound'].m1_rate) | number:'1.0-2'}}
+                </td>
+                <td class="text-right">
+                    {{filterNaN(metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.notFound'].m5_rate) | number:'1.0-2'}}
+                </td>
+                <td class="text-right">
+                    {{filterNaN(metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.notFound'].m15_rate) | number:'1.0-2'}}
+                </td>
+            </tr>
+            <tr>
+                <td jhiTranslate="metrics.jvm.http.code.servererror">Server error</td>
+                <td>
+                    <ngb-progressbar [max]="metrics.timers['com.codahale.metrics.servlet.InstrumentedFilter.requests'].count" [value]="metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.serverError'].count" [striped]="true" [animated]="false" type="success">
+                        <span>{{metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.serverError'].count}}</span>
+                    </ngb-progressbar>
+                </td>
+                <td class="text-right">
+                    {{filterNaN(metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.serverError'].mean_rate) | number:'1.0-2'}}
+                </td>
+                <td class="text-right">
+                    {{filterNaN(metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.serverError'].m1_rate) | number:'1.0-2'}}
+                </td>
+                <td class="text-right">
+                    {{filterNaN(metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.serverError'].m5_rate) | number:'1.0-2'}}
+                </td>
+                <td class="text-right">
+                    {{filterNaN(metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.serverError'].m15_rate) | number:'1.0-2'}}
+                </td>
+            </tr>
+            </tbody>
+        </table>
+    </div>
 
+    <h3 jhiTranslate="metrics.servicesstats.title">Services statistics (time in millisecond)</h3>
+    <div class="table-responsive" *ngIf="!updatingMetrics">
+        <table class="table table-striped">
+            <thead>
+            <tr>
+                <th jhiTranslate="metrics.servicesstats.table.name">Service name</th>
+                <th class="text-right" jhiTranslate="metrics.servicesstats.table.count">Count</th>
+                <th class="text-right" jhiTranslate="metrics.servicesstats.table.mean">Mean</th>
+                <th class="text-right" jhiTranslate="metrics.servicesstats.table.min">Min</th>
+                <th class="text-right" jhiTranslate="metrics.servicesstats.table.p50">p50</th>
+                <th class="text-right" jhiTranslate="metrics.servicesstats.table.p75">p75</th>
+                <th class="text-right" jhiTranslate="metrics.servicesstats.table.p95">p95</th>
+                <th class="text-right" jhiTranslate="metrics.servicesstats.table.p99">p99</th>
+                <th class="text-right" jhiTranslate="metrics.servicesstats.table.max">Max</th>
+            </tr>
+            </thead>
+            <tbody>
+            <tr *ngFor="let entry of servicesStats | keys">
+                <td>{{entry.key}}</td>
+                <td class="text-right">{{entry.value.count}}</td>
+                <td class="text-right">{{entry.value.mean * 1024 | number:'1.0-0'}}</td>
+                <td class="text-right">{{entry.value.min * 1024 | number:'1.0-0'}}</td>
+                <td class="text-right">{{entry.value.p50 * 1024 | number:'1.0-0'}}</td>
+                <td class="text-right">{{entry.value.p75 * 1024 | number:'1.0-0'}}</td>
+                <td class="text-right">{{entry.value.p95 * 1024 | number:'1.0-0'}}</td>
+                <td class="text-right">{{entry.value.p99 * 1024 | number:'1.0-0'}}</td>
+                <td class="text-right">{{entry.value.max * 1024 | number:'1.0-0'}}</td>
+            </tr>
+            </tbody>
+        </table>
+    </div>
+<% if (['ehcache', 'infinispan'].includes(cacheProvider)) { %>
+    <h3 jhiTranslate="metrics.cache.title">Cache statistics</h3>
+    <div class="table-responsive" *ngIf="!updatingMetrics">
+        <table class="table table-striped">
+            <thead>
+            <tr>
+                <th jhiTranslate="metrics.cache.cachename">Cache name</th>
+                <th class="text-right" data-translate="metrics.cache.hits">Cache Hits</th>
+                <th class="text-right" data-translate="metrics.cache.misses">Cache Misses</th>
+                <th class="text-right" data-translate="metrics.cache.gets">Cache Gets</th>
+                <th class="text-right" data-translate="metrics.cache.puts">Cache Puts</th>
+                <th class="text-right" data-translate="metrics.cache.removals">Cache Removals</th>
+                <th class="text-right" data-translate="metrics.cache.evictions">Cache Evictions</th>
+                <th class="text-right" data-translate="metrics.cache.hitPercent">Cache Hit %</th>
+                <th class="text-right" data-translate="metrics.cache.missPercent">Cache Miss %</th>
+                <th class="text-right" data-translate="metrics.cache.averageGetTime">Average get time (µs)</th>
+                <th class="text-right" data-translate="metrics.cache.averagePutTime">Average put time (µs)</th>
+                <th class="text-right" data-translate="metrics.cache.averageRemoveTime">Average remove time (µs)</th>
+            </tr>
+            </thead>
+            <tbody>
+            <tr *ngFor="let entry of cachesStats | keys">
+                <td>{{entry.key}}</td>
+                <td class="text-right">{{metrics.gauges[entry.key + '.cache-hits'].value}}</td>
+                <td class="text-right">{{metrics.gauges[entry.key + '.cache-misses'].value}}</td>
+                <td class="text-right">{{metrics.gauges[entry.key + '.cache-gets'].value}}</td>
+                <td class="text-right">{{metrics.gauges[entry.key + '.cache-puts'].value}}</td>
+                <td class="text-right">{{metrics.gauges[entry.key + '.cache-removals'].value}}</td>
+                <td class="text-right">{{metrics.gauges[entry.key + '.cache-evictions'].value}}</td>
+                <td class="text-right">{{metrics.gauges[entry.key + '.cache-hit-percentage'].value}}</td>
+                <td class="text-right">{{metrics.gauges[entry.key + '.cache-miss-percentage'].value }}</td>
+                <td class="text-right">{{filterNaN(metrics.gauges[entry.key + '.average-get-time'].value)  | number : '1.2-2' }}</td>
+                <td class="text-right">{{filterNaN(metrics.gauges[entry.key + '.average-put-time'].value)  | number : '1.2-2'}}</td>
+                <td class="text-right">{{filterNaN(metrics.gauges[entry.key + '.average-remove-time'].value) | number : '1.2-2' }}</td>
+            </tr>
+            </tbody>
+        </table>
+    </div>
+<%_ } _%>
+    <h3 jhiTranslate="metrics.datasource.title" *ngIf="metrics.gauges && metrics.gauges['HikariPool-1.pool.TotalConnections'] && metrics.gauges['HikariPool-1.pool.TotalConnections'].value > 0">DataSource statistics (time in millisecond)</h3>
+    <div class="table-responsive" *ngIf="!updatingMetrics && metrics.gauges && metrics.gauges['HikariPool-1.pool.TotalConnections'] && metrics.gauges['HikariPool-1.pool.TotalConnections'].value > 0">
+        <table class="table table-striped">
+            <thead>
+                <tr>
+                    <th><span jhiTranslate="metrics.datasource.usage">Usage</span> ({{metrics.gauges['HikariPool-1.pool.ActiveConnections'].value}} / {{metrics.gauges['HikariPool-1.pool.TotalConnections'].value}})</th>
+                    <th class="text-right" jhiTranslate="metrics.datasource.count">Count</th>
+                    <th class="text-right" jhiTranslate="metrics.datasource.mean">Mean</th>
+                    <th class="text-right" jhiTranslate="metrics.datasource.min">Min</th>
+                    <th class="text-right" jhiTranslate="metrics.datasource.p50">p50</th>
+                    <th class="text-right" jhiTranslate="metrics.datasource.p75">p75</th>
+                    <th class="text-right" jhiTranslate="metrics.datasource.p95">p95</th>
+                    <th class="text-right" jhiTranslate="metrics.datasource.p99">p99</th>
+                    <th class="text-right" jhiTranslate="metrics.datasource.max">Max</th>
+                </tr>
+            </thead>
+            <tbody>
+                <tr>
+                    <td>
+                        <div class="progress progress-striped">
+                            <ngb-progressbar [max]="metrics.gauges['HikariPool-1.pool.TotalConnections'].value" [value]="metrics.gauges['HikariPool-1.pool.ActiveConnections'].value" [striped]="true" [animated]="false" type="success">
+                                <span>{{metrics.gauges['HikariPool-1.pool.ActiveConnections'].value * 100 / metrics.gauges['HikariPool-1.pool.TotalConnections'].value  | number:'1.0-0'}}%</span>
+                            </ngb-progressbar>
+                        </div>
+                    </td>
+                    <td class="text-right">{{metrics.histograms['HikariPool-1.pool.Usage'].count}}</td>
+                    <td class="text-right">{{filterNaN(metrics.histograms['HikariPool-1.pool.Usage'].mean) | number:'1.0-2'}}</td>
+                    <td class="text-right">{{filterNaN(metrics.histograms['HikariPool-1.pool.Usage'].min) | number:'1.0-2'}}</td>
+                    <td class="text-right">{{filterNaN(metrics.histograms['HikariPool-1.pool.Usage'].p50) | number:'1.0-2'}}</td>
+                    <td class="text-right">{{filterNaN(metrics.histograms['HikariPool-1.pool.Usage'].p75) | number:'1.0-2'}}</td>
+                    <td class="text-right">{{filterNaN(metrics.histograms['HikariPool-1.pool.Usage'].p95) | number:'1.0-2'}}</td>
+                    <td class="text-right">{{filterNaN(metrics.histograms['HikariPool-1.pool.Usage'].p99) | number:'1.0-2'}}</td>
+                    <td class="text-right">{{filterNaN(metrics.histograms['HikariPool-1.pool.Usage'].max) | number:'1.0-2'}}</td>
+                </tr>
+            </tbody>
+        </table>
+    </div>
 </div>
diff --git a/generators/client/templates/angular/src/main/webapp/app/admin/metrics/metrics.component.ts.ejs b/generators/client/templates/angular/src/main/webapp/app/admin/metrics/metrics.component.ts.ejs
index 0c54e1ebf4..de351fc65c 100644
--- a/generators/client/templates/angular/src/main/webapp/app/admin/metrics/metrics.component.ts.ejs
+++ b/generators/client/templates/angular/src/main/webapp/app/admin/metrics/metrics.component.ts.ejs
@@ -16,9 +16,10 @@
  See the License for the specific language governing permissions and
  limitations under the License.
 -%>
-import {Component, OnInit} from '@angular/core';
-import {NgbModal} from '@ng-bootstrap/ng-bootstrap';
+import { Component, OnInit } from '@angular/core';
+import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
 
+import { <%=jhiPrefixCapitalized%>MetricsMonitoringModalComponent } from './metrics-modal.component';
 import { <%=jhiPrefixCapitalized%>MetricsService } from './metrics.service';
 
 @Component({
@@ -27,7 +28,8 @@ import { <%=jhiPrefixCapitalized%>MetricsService } from './metrics.service';
 })
 export class <%=jhiPrefixCapitalized%>MetricsMonitoringComponent implements OnInit {
     metrics: any = {};
-    threadData: any = {};
+    cachesStats: any = {};
+    servicesStats: any = {};
     updatingMetrics = true;
     JCACHE_KEY: string;
 
@@ -44,13 +46,51 @@ export class <%=jhiPrefixCapitalized%>MetricsMonitoringComponent implements OnIn
 
     refresh() {
         this.updatingMetrics = true;
-        this.metricsService.getMetrics().subscribe(metrics => {
+        this.metricsService.getMetrics().subscribe((metrics) => {
             this.metrics = metrics;
-            this.metricsService.threadDump().subscribe(data => {
-                this.threadData = data.threads;
-                this.updatingMetrics = false;
+            this.updatingMetrics = false;
+            this.servicesStats = {};
+            this.cachesStats = {};
+            Object.keys(metrics.timers).forEach((key) => {
+                const value = metrics.timers[key];
+                if (key.includes('web.rest') || key.includes('service')) {
+                    this.servicesStats[key] = value;
+                }
+            });
+            Object.keys(metrics.gauges).forEach((key) => {
+                if (key.includes('jcache.statistics')) {
+                    const value = metrics.gauges[key].value;
+                    // remove gets or puts
+                    const index = key.lastIndexOf('.');
+                    const newKey = key.substr(0, index);
+
+                    // Keep the name of the domain
+                    this.cachesStats[newKey] = {
+                        name: this.JCACHE_KEY.length,
+                        value
+                    };
+                }
+            });
+        });
+    }
+
+    refreshThreadDumpData() {
+        this.metricsService.threadDump().subscribe((data) => {
+            const modalRef  = this.modalService.open(<%=jhiPrefixCapitalized%>MetricsMonitoringModalComponent, { size: 'lg'});
+            modalRef.componentInstance.threadDump = data.threads;
+            modalRef.result.then((result) => {
+                // Left blank intentionally, nothing to do here
+            }, (reason) => {
+                // Left blank intentionally, nothing to do here
             });
         });
     }
 
+    filterNaN(input) {
+        if (isNaN(input)) {
+            return 0;
+        }
+        return input;
+    }
+
 }
diff --git a/generators/client/templates/angular/src/main/webapp/app/admin/metrics/metrics.service.ts.ejs b/generators/client/templates/angular/src/main/webapp/app/admin/metrics/metrics.service.ts.ejs
index 1bcd89ff3d..7606875043 100644
--- a/generators/client/templates/angular/src/main/webapp/app/admin/metrics/metrics.service.ts.ejs
+++ b/generators/client/templates/angular/src/main/webapp/app/admin/metrics/metrics.service.ts.ejs
@@ -28,7 +28,7 @@ export class <%=jhiPrefixCapitalized%>MetricsService {
     constructor(private http: HttpClient) {}
 
     getMetrics(): Observable<any> {
-        return this.http.get(SERVER_API_URL + 'management/jhi-metrics');
+        return this.http.get(SERVER_API_URL + 'management/metrics');
     }
 
     threadDump(): Observable<any> {
diff --git a/generators/client/templates/react/package.json.ejs b/generators/client/templates/react/package.json.ejs
index 0220d81dbc..eaccc8d373 100644
--- a/generators/client/templates/react/package.json.ejs
+++ b/generators/client/templates/react/package.json.ejs
@@ -41,7 +41,7 @@ limitations under the License.
     "react-addons-transition-group": "16.0.0-alpha.3",
     "react-dom": "16.4.2",
     "react-hot-loader": "3.1.1",
-    "react-jhipster": "0.6.0",
+    "react-jhipster": "0.5.9",
     "react-loadable": "5.5.0",
     "react-redux": "5.0.7",
     "react-redux-loading-bar": "4.0.5",
diff --git a/generators/client/templates/react/src/main/webapp/app/modules/administration/administration.reducer.ts.ejs b/generators/client/templates/react/src/main/webapp/app/modules/administration/administration.reducer.ts.ejs
index d486e2723e..80a8087462 100644
--- a/generators/client/templates/react/src/main/webapp/app/modules/administration/administration.reducer.ts.ejs
+++ b/generators/client/templates/react/src/main/webapp/app/modules/administration/administration.reducer.ts.ejs
@@ -192,7 +192,7 @@ export const systemHealth = () => ({
 
 export const systemMetrics = () => ({
   type: ACTION_TYPES.FETCH_METRICS,
-  payload: axios.get('management/jhi-metrics')
+  payload: axios.get('management/metrics')
 });
 
 export const systemThreadDump = () => ({
diff --git a/generators/client/templates/react/src/main/webapp/app/modules/administration/metrics/metrics.tsx.ejs b/generators/client/templates/react/src/main/webapp/app/modules/administration/metrics/metrics.tsx.ejs
index c74487d967..0cf9ff88ea 100644
--- a/generators/client/templates/react/src/main/webapp/app/modules/administration/metrics/metrics.tsx.ejs
+++ b/generators/client/templates/react/src/main/webapp/app/modules/administration/metrics/metrics.tsx.ejs
@@ -18,22 +18,13 @@
 -%>
 import React from 'react';
 import { connect } from 'react-redux';
-import { Button, Col, Progress, Row, Table } from 'reactstrap';
-import {
-  CacheMetrics,
-  DatasourceMetrics,
-  GarbageCollectorMetrics,
-  HttpRequestMetrics,
-  JvmMemory,
-  JvmThreads,
-  EndpointsRequestsMetrics,
-  SystemMetrics,
-  Translate
-} from 'react-jhipster';
+import { Table, Progress, Col, Row, Button } from 'reactstrap';
+import { Translate, TextFormat } from 'react-jhipster';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 
-import { APP_TIMESTAMP_FORMAT, APP_TWO_DIGITS_AFTER_POINT_NUMBER_FORMAT, APP_WHOLE_NUMBER_FORMAT } from 'app/config/constants';
+import { APP_WHOLE_NUMBER_FORMAT, APP_TWO_DIGITS_AFTER_POINT_NUMBER_FORMAT } from 'app/config/constants';
 import { systemMetrics, systemThreadDump } from '../administration.reducer';
+import MetricsModal from './metrics-modal';
 import { IRootState } from 'app/shared/reducers';
 
 export interface IMetricsPageProps extends StateProps, DispatchProps {}
@@ -49,87 +40,565 @@ export class MetricsPage extends React.Component<IMetricsPageProps, IMetricsPage
 
   componentDidMount() {
     this.props.systemMetrics();
-    this.props.systemThreadDump();
   }
 
   getMetrics = () => {
     if (!this.props.isFetching) {
       this.props.systemMetrics();
-      this.props.systemThreadDump();
     }
   }
 
+  getThreadDump = () => {
+    this.props.systemThreadDump();
+    this.setState({
+      showModal: true
+    });
+  }
+
+  handleClose = () => {
+    this.setState({
+        showModal: false
+    });
+  }
+
+  filterNaN = input => isNaN(input) ? 0 : input;
+
+  getStats = metrics => {
+    const stat = {
+      servicesStats: {},
+      cachesStats: {}
+    };
+    if (!this.props.isFetching && metrics && metrics.timers) {
+      Object.keys(metrics.timers).forEach((key, indexNm) => {
+        if (key.indexOf('web.rest') !== -1 || key.indexOf('service') !== -1) {
+          stat.servicesStats[key] = metrics.timers[key];
+        }
+        if (key.indexOf('net.sf.ehcache.Cache') !== -1) {
+          // remove gets or puts
+          const index = key.lastIndexOf('.');
+          const newKey = key.substr(0, index);
+          // Keep the name of the domain
+          stat.cachesStats[newKey] = {
+            name: newKey,
+            value: metrics.timers[key]
+          };
+        }
+      });
+
+    }
+    return stat;
+  }
+
+  gaugeRow = (metrics, label: String, key) => (
+    metrics.gauges[key] ?
+      <Row>
+        <Col md="9">{label}</Col>
+        <Col md="3" className="text-right">
+          {metrics.gauges[key].value}
+        </Col>
+      </Row>
+      : null
+  );
+
+  renderModal = () => <MetricsModal handleClose={this.handleClose} showModal={this.state.showModal} threadDump={this.props.threadDump}/>;
+
+  renderGauges = metrics => (
+    <Row>
+      <Col sm="12">
+        <h3>JVM Metrics</h3>
+        <Row>
+          <Col md="4">
+            <b>Memory</b>
+            <p>
+              <span>Total Memory</span> (
+                <TextFormat
+                  value={metrics.gauges['jvm.memory.total.used'].value / 1048576}
+                  type="number"
+                  format={APP_WHOLE_NUMBER_FORMAT} />
+                M / <TextFormat
+                  value={metrics.gauges['jvm.memory.total.max'].value / 1048576}
+                  type="number"
+                  format={APP_WHOLE_NUMBER_FORMAT} />
+                M)
+            </p>
+            <Progress animated
+              value={metrics.gauges['jvm.memory.total.used'].value}
+              min="0"
+              max={metrics.gauges['jvm.memory.total.max'].value}
+              color="success"
+            >
+              <span>
+                <TextFormat
+                value={metrics.gauges['jvm.memory.total.used'].value * 100 / metrics.gauges['jvm.memory.total.max'].value}
+                type="number"
+                format={APP_WHOLE_NUMBER_FORMAT} />
+                %
+              </span>
+            </Progress>
+            <p>
+              <span>Heap Memory</span> (
+                <TextFormat
+                  value={metrics.gauges['jvm.memory.heap.used'].value / 1048576}
+                  type="number"
+                  format={APP_WHOLE_NUMBER_FORMAT} />
+                M / <TextFormat
+                  value={metrics.gauges['jvm.memory.heap.max'].value / 1048576}
+                  type="number"
+                  format={APP_WHOLE_NUMBER_FORMAT} />
+                M)
+            </p>
+            <Progress animated
+              min="0"
+              max={metrics.gauges['jvm.memory.heap.max'].value}
+              value={metrics.gauges['jvm.memory.heap.used'].value}
+              color="success"
+            >
+              <span>
+                <TextFormat
+                  value={metrics.gauges['jvm.memory.heap.used'].value * 100 / metrics.gauges['jvm.memory.heap.max'].value}
+                  type="number"
+                  format={APP_WHOLE_NUMBER_FORMAT} />
+                %
+              </span>
+            </Progress>
+
+            <p>
+              <span>Non-Heap Memory</span> (
+                <TextFormat
+                  value={metrics.gauges['jvm.memory.non-heap.used'].value / 1048576}
+                  type="number"
+                  format={APP_WHOLE_NUMBER_FORMAT} />
+                M / <TextFormat
+                  value={metrics.gauges['jvm.memory.non-heap.committed'].value / 1048576}
+                  type="number"
+                  format={APP_WHOLE_NUMBER_FORMAT} />
+                M)
+            </p>
+            <Progress animated
+              min="0"
+              max={metrics.gauges['jvm.memory.non-heap.committed'].value}
+              value={metrics.gauges['jvm.memory.non-heap.used'].value}
+              color="success"
+            >
+              <span>
+                <TextFormat
+                  value={metrics.gauges['jvm.memory.non-heap.used'].value * 100 / metrics.gauges['jvm.memory.non-heap.committed'].value}
+                  type="number"
+                  format={APP_WHOLE_NUMBER_FORMAT} />
+                %
+              </span>
+            </Progress>
+          </Col>
+          <Col md="4">
+            <b>Threads</b> (Total: {metrics.gauges['jvm.threads.count'].value}){' '}
+            <Button color="link" className="hand" onClick={this.getThreadDump}><FontAwesomeIcon icon="eye" /></Button>
+            <p><span>Runnable</span> {metrics.gauges['jvm.threads.runnable.count'].value}</p>
+            <Progress animated min="0" value={metrics.gauges['jvm.threads.runnable.count'].value} max={metrics.gauges['jvm.threads.count'].value} color="success">
+              <span>
+                <TextFormat
+                  value={metrics.gauges['jvm.threads.runnable.count'].value * 100 / metrics.gauges['jvm.threads.count'].value}
+                  type="number"
+                  format={APP_WHOLE_NUMBER_FORMAT} />
+                %
+              </span>
+            </Progress>
+
+            <p><span>Timed Waiting</span> ({metrics.gauges['jvm.threads.timed_waiting.count'].value})</p>
+            <Progress animated min="0" value={metrics.gauges['jvm.threads.timed_waiting.count'].value} max={metrics.gauges['jvm.threads.count'].value} color="warning">
+              <span>
+                <TextFormat
+                  value={metrics.gauges['jvm.threads.timed_waiting.count'].value * 100 / metrics.gauges['jvm.threads.count'].value}
+                  type="number"
+                  format={APP_WHOLE_NUMBER_FORMAT} />
+                %
+              </span>
+            </Progress>
+
+            <p><span>Waiting</span> ({metrics.gauges['jvm.threads.waiting.count'].value})</p>
+            <Progress animated min="0" value={metrics.gauges['jvm.threads.waiting.count'].value} max={metrics.gauges['jvm.threads.count'].value} color="warning">
+              <span>
+                <TextFormat
+                  value={metrics.gauges['jvm.threads.waiting.count'].value * 100 / metrics.gauges['jvm.threads.count'].value}
+                  type="number"
+                  format={APP_WHOLE_NUMBER_FORMAT} />
+                %
+              </span>
+            </Progress>
+
+            <p><span>Blocked</span> ({metrics.gauges['jvm.threads.blocked.count'].value})</p>
+            <Progress animated min="0" value={metrics.gauges['jvm.threads.blocked.count'].value} max={metrics.gauges['jvm.threads.count'].value} color="success">
+              <span>
+                <TextFormat
+                  value={metrics.gauges['jvm.threads.blocked.count'].value * 100 / metrics.gauges['jvm.threads.count'].value}
+                  type="number"
+                  format={APP_WHOLE_NUMBER_FORMAT} />
+                %
+              </span>
+            </Progress>
+          </Col>
+          <Col md="4">
+            <b>Garbage collections</b>
+            {this.gaugeRow(metrics, 'Mark Sweep count', 'jvm.garbage.PS-MarkSweep.count')}
+            {this.gaugeRow(metrics, 'Mark Sweep time', 'jvm.garbage.PS-MarkSweep.time')}
+            {this.gaugeRow(metrics, 'Scavenge count', 'jvm.garbage.PS-Scavenge.count')}
+            {this.gaugeRow(metrics, 'Scavenge time', 'jvm.garbage.PS-Scavenge.time')}
+          </Col>
+        </Row>
+      </Col>
+    </Row>
+    )
+
   render() {
-    const {metrics, threadDump, isFetching} = this.props;
+    const { metrics, isFetching } = this.props;
+    const data = metrics || {};
+    const { servicesStats, cachesStats } = this.getStats(data);
     return (
-      <div>
-        <h2 id="metrics-page-heading">Application Metrics</h2>
-        <p>
-          <Button onClick={this.getMetrics} color={isFetching ? 'btn btn-danger' : 'btn btn-primary'}
-                  disabled={isFetching}>
-            <FontAwesomeIcon icon="sync"/>
-            &nbsp;
-            <Translate component="span" contentKey="health.refresh.button">
-              Refresh
-            </Translate>
-          </Button>
-        </p>
-        <hr/>
+        <div>
+          <h2 id="metrics-page-heading">Application Metrics</h2>
+          <p>
+            <Button onClick={this.getMetrics} color={isFetching ? 'btn btn-danger' : 'btn btn-primary'} disabled={isFetching}>
+              <FontAwesomeIcon icon="sync" />&nbsp;
+              <Translate component="span" contentKey="health.refresh.button">Refresh</Translate>
+            </Button>
+          </p>
+          <hr />
+          {metrics.gauges ? this.renderGauges(metrics) : ''}
 
-        <Row>
-          <Col sm="12">
-            <h3>JVM Metrics</h3>
+          { metrics.meters && metrics.timers ?
             <Row>
-              <Col md="4">
-                {metrics && metrics.jvm ?
-                  <JvmMemory jvmMetrics={metrics.jvm} wholeNumberFormat={APP_WHOLE_NUMBER_FORMAT}/> : ''}
-              </Col>
-              <Col md="4">
-                {threadDump ?
-                  <JvmThreads jvmThreads={threadDump} wholeNumberFormat={APP_WHOLE_NUMBER_FORMAT}/> : ''}
-              </Col>
-              <Col md="4">
-                {metrics && metrics.processMetrics ?
-                  <SystemMetrics systemMetrics={metrics.processMetrics} wholeNumberFormat={APP_WHOLE_NUMBER_FORMAT}
-                                 timestampFormat={APP_TIMESTAMP_FORMAT}/> : ''}
+              <Col sm="12">
+                <h3>HTTP requests (events per second)</h3>
+                <p>
+                  <span>Active requests:</span> <b>
+                    <TextFormat
+                      value={metrics.counters['com.codahale.metrics.servlet.InstrumentedFilter.activeRequests'].count}
+                      type="number"
+                      format={APP_WHOLE_NUMBER_FORMAT} />
+                  </b> - <span>Total requests:</span> <b>
+                    <TextFormat
+                      value={metrics.timers['com.codahale.metrics.servlet.InstrumentedFilter.requests'].count}
+                      type="number"
+                      format={APP_WHOLE_NUMBER_FORMAT} />
+                  </b>
+                </p>
+                <Table>
+                  <thead>
+                    <tr>
+                      <th>Code</th>
+                      <th>Count</th>
+                      <th className="text-right">Mean</th>
+                      <th className="text-right"><span>Average</span> (1 min)</th>
+                      <th className="text-right"><span>Average</span> (5 min)</th>
+                      <th className="text-right"><span>Average</span> (15 min)</th>
+                    </tr>
+                  </thead>
+                  <tbody>
+                    <tr key={0}>
+                      <td>OK</td>
+                      <td>
+                        <Progress
+                          min="0"
+                          max={metrics.timers['com.codahale.metrics.servlet.InstrumentedFilter.requests'].count}
+                          value={metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.ok'].count}
+                          color="success"
+                          animated
+                        />
+                      </td>
+                      <td className="text-right">
+                        <TextFormat
+                          value={this.filterNaN(metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.ok'].mean_rate)}
+                          type="number"
+                          format={APP_TWO_DIGITS_AFTER_POINT_NUMBER_FORMAT} />
+                      </td>
+                      <td className="text-right">
+                        <TextFormat
+                          value={this.filterNaN(metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.ok'].m1_rate)}
+                          type="number"
+                          format={APP_TWO_DIGITS_AFTER_POINT_NUMBER_FORMAT} />
+                      </td>
+                      <td className="text-right">
+                        <TextFormat
+                          value={this.filterNaN(metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.ok'].m5_rate)}
+                          type="number"
+                          format={APP_TWO_DIGITS_AFTER_POINT_NUMBER_FORMAT} />
+                      </td>
+                      <td className="text-right">
+                        <TextFormat
+                          value={this.filterNaN(metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.ok'].m15_rate)}
+                          type="number"
+                          format={APP_TWO_DIGITS_AFTER_POINT_NUMBER_FORMAT} />
+                      </td>
+                    </tr>
+                    <tr key={1}>
+                      <td>Not Found</td>
+                      <td>
+                        <Progress
+                          min="0"
+                          max={metrics.timers['com.codahale.metrics.servlet.InstrumentedFilter.requests'].count}
+                          value={metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.notFound'].count}
+                          color="success"
+                          animated
+                        />
+                      </td>
+                      <td className="text-right">
+                        <TextFormat
+                          value={this.filterNaN(metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.notFound'].mean_rate)}
+                          type="number"
+                          format={APP_TWO_DIGITS_AFTER_POINT_NUMBER_FORMAT} />
+                      </td>
+                      <td className="text-right">
+                        <TextFormat
+                          value={this.filterNaN(metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.notFound'].m1_rate)}
+                          type="number"
+                          format={APP_TWO_DIGITS_AFTER_POINT_NUMBER_FORMAT} />
+                      </td>
+                      <td className="text-right">
+                        <TextFormat
+                          value={this.filterNaN(metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.notFound'].m5_rate)}
+                          type="number"
+                          format={APP_TWO_DIGITS_AFTER_POINT_NUMBER_FORMAT} />
+                      </td>
+                      <td className="text-right">
+                        <TextFormat
+                          value={this.filterNaN(metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.notFound'].m15_rate)}
+                          type="number"
+                          format={APP_TWO_DIGITS_AFTER_POINT_NUMBER_FORMAT} />
+                      </td>
+                    </tr>
+                    <tr key={2}>
+                      <td>Server Error</td>
+                      <td>
+                        <Progress
+                          min="0"
+                          max={metrics.timers['com.codahale.metrics.servlet.InstrumentedFilter.requests'].count}
+                          value={metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.serverError'].count}
+                          color="success"
+                          animated
+                        />
+                      </td>
+                      <td className="text-right">
+                        <TextFormat
+                          value={this.filterNaN(metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.serverError'].mean_rate)}
+                          type="number"
+                          format={APP_TWO_DIGITS_AFTER_POINT_NUMBER_FORMAT} />
+                      </td>
+                      <td className="text-right">
+                        <TextFormat
+                          value={this.filterNaN(metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.serverError'].m1_rate)}
+                          type="number"
+                          format={APP_TWO_DIGITS_AFTER_POINT_NUMBER_FORMAT} />
+                      </td>
+                      <td className="text-right">
+                        <TextFormat
+                          value={this.filterNaN(metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.serverError'].m5_rate)}
+                          type="number"
+                          format={APP_TWO_DIGITS_AFTER_POINT_NUMBER_FORMAT} />
+                      </td>
+                      <td className="text-right">
+                        <TextFormat
+                          value={this.filterNaN(metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.serverError'].m15_rate)}
+                          type="number"
+                          format={APP_TWO_DIGITS_AFTER_POINT_NUMBER_FORMAT} />
+                      </td>
+                    </tr>
+                  </tbody>
+                </Table>
               </Col>
             </Row>
-          </Col>
-        </Row>
-
-        {metrics && metrics.garbageCollector ?
-          <GarbageCollectorMetrics garbageCollectorMetrics={metrics.garbageCollector}
-                                   wholeNumberFormat={APP_WHOLE_NUMBER_FORMAT}/> : ''}
-        {metrics && metrics['http.server.requests'] ?
-          <HttpRequestMetrics requestMetrics={metrics['http.server.requests']}
-                              twoDigitAfterPointFormat={APP_TWO_DIGITS_AFTER_POINT_NUMBER_FORMAT}
-                              wholeNumberFormat={APP_WHOLE_NUMBER_FORMAT}/> : ''}
-        {metrics && metrics.endpointsRequests ?
-          <EndpointsRequestsMetrics endpointsRequestsMetrics={metrics.endpointsRequests} wholeNumberFormat={APP_WHOLE_NUMBER_FORMAT}/> : ''}
-
-        {metrics.cache ? (
+          : ''}
+          { servicesStats ?
           <Row>
             <Col sm="12">
-              <CacheMetrics cacheMetrics={metrics.cache}
-                            twoDigitAfterPointFormat={APP_TWO_DIGITS_AFTER_POINT_NUMBER_FORMAT}/>
+              <h3>Services statistics (time in millisecond)</h3>
             </Col>
+            <Table>
+              <thead>
+                <tr>
+                  <th>Service name</th>
+                  <th>Count</th>
+                  <th>Mean</th>
+                  <th>Min</th>
+                  <th>p50</th>
+                  <th>p75</th>
+                  <th>p95</th>
+                  <th>p99</th>
+                  <th>Max</th>
+                </tr>
+              </thead>
+              <tbody>
+                {Object.keys(servicesStats).map((key, index) => (
+                  <tr key={key}>
+                    <td>{key}</td>
+                    <td>{servicesStats[key].count}</td>
+                    <td>
+                      <TextFormat
+                        value={servicesStats[key].mean * 1024}
+                        type="number"
+                        format={APP_WHOLE_NUMBER_FORMAT} />
+                    </td>
+                    <td>
+                      <TextFormat
+                        value={servicesStats[key].min * 1024}
+                        type="number"
+                        format={APP_WHOLE_NUMBER_FORMAT} />
+                    </td>
+                    <td>
+                      <TextFormat
+                        value={servicesStats[key].p50 * 1024}
+                        type="number"
+                        format={APP_WHOLE_NUMBER_FORMAT} />
+                    </td>
+                    <td>
+                      <TextFormat
+                        value={servicesStats[key].p75 * 1024}
+                        type="number"
+                        format={APP_WHOLE_NUMBER_FORMAT} />
+                    </td>
+                    <td>
+                      <TextFormat
+                        value={servicesStats[key].p95 * 1024}
+                        type="number"
+                        format={APP_WHOLE_NUMBER_FORMAT} />
+                    </td>
+                    <td>
+                      <TextFormat
+                        value={servicesStats[key].p99 * 1024}
+                        type="number"
+                        format={APP_WHOLE_NUMBER_FORMAT} />
+                    </td>
+                    <td>
+                      <TextFormat
+                        value={servicesStats[key].max * 1024}
+                        type="number"
+                        format={APP_WHOLE_NUMBER_FORMAT} />
+                    </td>
+                  </tr>
+                ))}
+              </tbody>
+            </Table>
           </Row>
-        ) : (
-          ''
-        )}
+          : ''}
 
-        {metrics.databases ? (
-          <Row>
-            <Col sm="12">
-              <DatasourceMetrics datasourceMetrics={metrics.databases}
-                                 twoDigitAfterPointFormat={APP_TWO_DIGITS_AFTER_POINT_NUMBER_FORMAT}/>
-            </Col>
-          </Row>
-        ) : (
-          ''
-        )}
+          { cachesStats ?
+            <Row>
+              <Col sm="12">
+                <h3>Ehcache statistics</h3>
+                <Table>
+                  <thead>
+                    <tr>
+                      <th>Cache Name</th>
+                      <th>Object</th>
+                      <th>Misses</th>
+                      <th>Eviction Count</th>
+                    </tr>
+                  </thead>
+                  <tbody>
+                    {Object.keys(cachesStats).map((k, v) => (
+                      <tr key={k}>
+                        <td>{k}</td>
+                        <td>{metrics.gauges[`${k}.objects`].value}</td>
+                        <td>{metrics.gauges[`${k}.hits`].value}</td>
+                        <td>{metrics.gauges[`${k}.misses`].value}</td>
+                        <td>{metrics.gauges[`${k}.eviction-count`].value}</td>
+                      </tr>
+                    ))}
+                  </tbody>
+                </Table>
+              </Col>
+            </Row>
+          : ''}
+
+          { metrics.gauges && metrics.gauges['HikariPool-1.pool.TotalConnections'] && metrics.gauges['HikariPool-1.pool.TotalConnections'].value > 0 ?
+            <Row>
+              <Col sm="12">
+                <h3>DataSource statistics (time in millisecond)</h3>
+                <Table>
+                  <thead>
+                    <tr>
+                      <th>
+                        <span>Usage</span>
+                        ({metrics.gauges['HikariPool-1.pool.ActiveConnections'].value} / {metrics.gauges['HikariPool-1.pool.TotalConnections'].value})
+                      </th>
+                      <th className="text-right">Count</th>
+                      <th className="text-right">Mean</th>
+                      <th className="text-right">Min</th>
+                      <th className="text-right">p50</th>
+                      <th className="text-right">p75</th>
+                      <th className="text-right">p95</th>
+                      <th className="text-right">p99</th>
+                      <th className="text-right">Max</th>
+                    </tr>
+                  </thead>
+                  <tbody>
+                    <tr key="DB">
+                      <td>
+                        <Progress
+                          min="0"
+                          max={metrics.gauges['HikariPool-1.pool.TotalConnections'].value}
+                          value={metrics.gauges['HikariPool-1.pool.ActiveConnections'].value}
+                        >
+                          <span>
+                            <TextFormat
+                              value={metrics.gauges['HikariPool-1.pool.ActiveConnections'].value * 100 / metrics.gauges['HikariPool-1.pool.TotalConnections'].value}
+                              type="number"
+                              format={APP_WHOLE_NUMBER_FORMAT} />
+                            %
+                          </span>
+                        </Progress>
+                      </td>
+                      <td className="text-right">{metrics.histograms['HikariPool-1.pool.Usage'].count}</td>
+                      <td className="text-right">
+                        <TextFormat
+                          value={this.filterNaN(metrics.histograms['HikariPool-1.pool.Usage'].mean)}
+                          type="number"
+                          format={APP_TWO_DIGITS_AFTER_POINT_NUMBER_FORMAT} />
+                      </td>
+                      <td className="text-right">
+                        <TextFormat
+                          value={this.filterNaN(metrics.histograms['HikariPool-1.pool.Usage'].min)}
+                          type="number"
+                          format={APP_TWO_DIGITS_AFTER_POINT_NUMBER_FORMAT} />
+                      </td>
+                      <td className="text-right">
+                        <TextFormat
+                          value={this.filterNaN(metrics.histograms['HikariPool-1.pool.Usage'].p50)}
+                          type="number"
+                          format={APP_TWO_DIGITS_AFTER_POINT_NUMBER_FORMAT} />
+                      </td>
+                      <td className="text-right">
+                        <TextFormat
+                          value={this.filterNaN(metrics.histograms['HikariPool-1.pool.Usage'].p75)}
+                          type="number"
+                          format={APP_TWO_DIGITS_AFTER_POINT_NUMBER_FORMAT} />
+                      </td>
+                      <td className="text-right">
+                        <TextFormat
+                          value={this.filterNaN(metrics.histograms['HikariPool-1.pool.Usage'].p95)}
+                          type="number"
+                          format={APP_TWO_DIGITS_AFTER_POINT_NUMBER_FORMAT} />
+                      </td>
+                      <td className="text-right">
+                        <TextFormat
+                          value={this.filterNaN(metrics.histograms['HikariPool-1.pool.Usage'].p99)}
+                          type="number"
+                          format={APP_TWO_DIGITS_AFTER_POINT_NUMBER_FORMAT} />
+                      </td>
+                      <td className="text-right">
+                        <TextFormat
+                          value={this.filterNaN(metrics.histograms['HikariPool-1.pool.Usage'].max)}
+                          type="number"
+                          format={APP_TWO_DIGITS_AFTER_POINT_NUMBER_FORMAT} />
+                      </td>
+                    </tr>
+                  </tbody>
+                </Table>
+              </Col>
+            </Row>
+          : '' }
+
+          {this.renderModal()}
 
-      </div>
+        </div>
     );
   }
 }
diff --git a/generators/entity-client/templates/angular/src/main/webapp/app/entities/entity-management-update.component.html.ejs b/generators/entity-client/templates/angular/src/main/webapp/app/entities/entity-management-update.component.html.ejs
index 1dbbf8314c..8283966316 100644
--- a/generators/entity-client/templates/angular/src/main/webapp/app/entities/entity-management-update.component.html.ejs
+++ b/generators/entity-client/templates/angular/src/main/webapp/app/entities/entity-management-update.component.html.ejs
@@ -94,7 +94,7 @@
                     </div>
                     <%_ } else if (['Instant', 'ZonedDateTime'].includes(fieldType)) { _%>
                     <div class="d-flex">
-                        <input id="field_<%= fieldName %>" type="<%= fieldInputType %>" class="form-control" name="<%= fieldName %>" [(ngModel)]="<%= fieldName %>" placeholder="YYYY-MM-DD HH:mm"
+                        <input id="field_<%= fieldName %>" type="<%= fieldInputType %>" class="form-control" name="<%= fieldName %>" [(ngModel)]="<%= fieldName %>"
                         <%- include ng_validators %>/>
                     </div>
                     <%_ } else if (fieldTypeBlobContent === 'text') { _%>
diff --git a/generators/entity-server/templates/src/main/java/package/common/get_all_template.ejs b/generators/entity-server/templates/src/main/java/package/common/get_all_template.ejs
index 40bac56661..bd6b628061 100644
--- a/generators/entity-server/templates/src/main/java/package/common/get_all_template.ejs
+++ b/generators/entity-server/templates/src/main/java/package/common/get_all_template.ejs
@@ -42,6 +42,7 @@
     * @return the ResponseEntity with status 200 (OK) and the count in body
     */
     @GetMapping("/<%= entityApiUrl %>/count")
+    @Timed
     public ResponseEntity<Long> count<%= entityClassPlural %>(<%= entityClass %>Criteria criteria) {
         log.debug("REST request to count <%= entityClassPlural %> by criteria: {}", criteria);
         return ResponseEntity.ok().body(<%= entityInstance %>QueryService.countByCriteria(criteria));
diff --git a/generators/entity-server/templates/src/main/java/package/web/rest/EntityResource.java.ejs b/generators/entity-server/templates/src/main/java/package/web/rest/EntityResource.java.ejs
index 494d356290..07a9e20dfd 100644
--- a/generators/entity-server/templates/src/main/java/package/web/rest/EntityResource.java.ejs
+++ b/generators/entity-server/templates/src/main/java/package/web/rest/EntityResource.java.ejs
@@ -18,6 +18,7 @@
 -%>
 package <%=packageName%>.web.rest;
 
+import com.codahale.metrics.annotation.Timed;
 <%_ if (dto !== 'mapstruct' || service === 'no') { _%>
 import <%=packageName%>.domain.<%= entityClass %>;
 <%_ } _%>
@@ -108,6 +109,7 @@ public class <%= entityClass %>Resource {
      * @throws URISyntaxException if the Location URI syntax is incorrect
      */
     @PostMapping("/<%= entityApiUrl %>")
+    @Timed
     public ResponseEntity<<%= instanceType %>> create<%= entityClass %>(<% if (validation) { %>@Valid <% } %>@RequestBody <%= instanceType %> <%= instanceName %>) throws URISyntaxException {
         log.debug("REST request to save <%= entityClass %> : {}", <%= instanceName %>);
         if (<%= instanceName %>.getId() != null) {
@@ -138,6 +140,7 @@ public class <%= entityClass %>Resource {
      * @throws URISyntaxException if the Location URI syntax is incorrect
      */
     @PutMapping("/<%= entityApiUrl %>")
+    @Timed
     public ResponseEntity<<%= instanceType %>> update<%= entityClass %>(<% if (validation) { %>@Valid <% } %>@RequestBody <%= instanceType %> <%= instanceName %>) throws URISyntaxException {
         log.debug("REST request to update <%= entityClass %> : {}", <%= instanceName %>);
         if (<%= instanceName %>.getId() == null) {
@@ -164,7 +167,8 @@ public class <%= entityClass %>Resource {
      * @param filter the filter of the request<% } %>
      * @return the ResponseEntity with status 200 (OK) and the list of <%= entityInstancePlural %> in body
      */
-    @GetMapping("/<%= entityApiUrl %>")<%- include('../../common/get_all_template', {viaService: viaService}); -%>
+    @GetMapping("/<%= entityApiUrl %>")
+    @Timed<%- include('../../common/get_all_template', {viaService: viaService}); -%>
 
     <%_ if (reactiveRepositories) { _%>
     /**
@@ -172,6 +176,7 @@ public class <%= entityClass %>Resource {
      * @return the Flux of <%= entityInstancePlural %>
      */
     @GetMapping(value = "/<%= entityApiUrl %>", produces = MediaType.APPLICATION_STREAM_JSON_VALUE)
+    @Timed
     public Flux<<%= instanceType %>> getAll<%= entityClassPlural %>AsStream() {
         log.debug("REST request to get all <%= entityClassPlural %> as a stream");
         <%_ if (viaService) { _%>
@@ -189,6 +194,7 @@ public class <%= entityClass %>Resource {
      * @return the ResponseEntity with status 200 (OK) and with body the <%= instanceName %>, or with status 404 (Not Found)
      */
     @GetMapping("/<%= entityApiUrl %>/{id}")
+    @Timed
     public ResponseEntity<<%= instanceType %>> get<%= entityClass %>(@PathVariable <%= pkType %> id) {
         log.debug("REST request to get <%= entityClass %> : {}", id);<%- include('../../common/get_template', {viaService: viaService, returnDirectly:false}); -%>
         return ResponseUtil.wrapOrNotFound(<%= instanceName %>);
@@ -201,6 +207,7 @@ public class <%= entityClass %>Resource {
      * @return the ResponseEntity with status 200 (OK)
      */
     @DeleteMapping("/<%= entityApiUrl %>/{id}")
+    @Timed
     public ResponseEntity<Void> delete<%= entityClass %>(@PathVariable <%= pkType %> id) {
         log.debug("REST request to delete <%= entityClass %> : {}", id);
 <%- include('../../common/delete_template', {viaService: viaService}); -%>
@@ -215,5 +222,6 @@ public class <%= entityClass %>Resource {
      * @param pageable the pagination information<% } %>
      * @return the result of the search
      */
-    @GetMapping("/_search/<%= entityApiUrl %>")<%- include('../../common/search_template', {viaService: viaService}); -%><% } %>
+    @GetMapping("/_search/<%= entityApiUrl %>")
+    @Timed<%- include('../../common/search_template', {viaService: viaService}); -%><% } %>
 }
diff --git a/generators/entity/index.js b/generators/entity/index.js
index aad753b773..1b8141b234 100644
--- a/generators/entity/index.js
+++ b/generators/entity/index.js
@@ -951,12 +951,7 @@ module.exports = class extends BaseBlueprintGenerator {
                             relationship.otherEntityModuleName = `${context.angularXAppName +
                                 relationship.otherEntityNameCapitalized}Module`;
                             relationship.otherEntityFileName = _.kebabCase(relationship.otherEntityAngularName);
-                            if (
-                                context.skipUiGrouping ||
-                                otherEntityData === undefined ||
-                                otherEntityData.clientRootFolder === '' ||
-                                otherEntityData.clientRootFolder === undefined
-                            ) {
+                            if (context.skipUiGrouping || otherEntityData === undefined || otherEntityData.clientRootFolder === '' || otherEntityData.clientRootFolder === undefined) {
                                 relationship.otherEntityClientRootFolder = '';
                             } else {
                                 relationship.otherEntityClientRootFolder = `${otherEntityData.clientRootFolder}/`;
diff --git a/generators/generator-constants.js b/generators/generator-constants.js
index 428a5c313f..822b74bd43 100644
--- a/generators/generator-constants.js
+++ b/generators/generator-constants.js
@@ -25,7 +25,7 @@ const DOCKER_MARIADB = 'mariadb:10.4.1';
 const DOCKER_POSTGRESQL = 'postgres:11.1';
 const DOCKER_MONGODB = 'mongo:4.0.4';
 const DOCKER_COUCHBASE = 'couchbase/server:6.0.0';
-const DOCKER_CASSANDRA = 'cassandra:3.9';
+const DOCKER_CASSANDRA = 'cassandra:3.11.3';
 const DOCKER_MSSQL = 'microsoft/mssql-server-linux:latest';
 const DOCKER_ORACLE = 'sath89/oracle-12c:latest';
 const DOCKER_HAZELCAST_MANAGEMENT_CENTER = 'hazelcast/management-center:3.11';
diff --git a/generators/languages/templates/src/main/webapp/i18n/en/metrics.json b/generators/languages/templates/src/main/webapp/i18n/en/metrics.json
index 7d379d206b..9d804947c5 100644
--- a/generators/languages/templates/src/main/webapp/i18n/en/metrics.json
+++ b/generators/languages/templates/src/main/webapp/i18n/en/metrics.json
@@ -39,15 +39,14 @@
                 "scavengetime": "Scavenge time"
             },
             "http": {
-                "title": "HTTP requests (time in millisecond)",
+                "title": "HTTP requests (events per second)",
                 "active": "Active requests:",
                 "total": "Total requests:",
                 "table": {
                     "code": "Code",
                     "count": "Count",
                     "mean": "Mean",
-                    "average": "Average",
-                    "max": "Max"
+                    "average": "Average"
                 },
                 "code": {
                     "ok": "Ok",
@@ -86,7 +85,7 @@
             "averageRemoveTime": "Average remove time (µs)"
         },
         "datasource": {
-            "usage": "Connection Pool Usage",
+            "usage": "Usage",
             "title": "DataSource statistics (time in millisecond)",
             "name": "Pool usage",
             "count": "Count",
diff --git a/generators/languages/templates/src/main/webapp/i18n/fr/metrics.json b/generators/languages/templates/src/main/webapp/i18n/fr/metrics.json
index b54d489216..e2006488c4 100644
--- a/generators/languages/templates/src/main/webapp/i18n/fr/metrics.json
+++ b/generators/languages/templates/src/main/webapp/i18n/fr/metrics.json
@@ -39,15 +39,14 @@
                 "scavengetime": "Temps \"Scavenge\""
             },
             "http": {
-                "title": "Requêtes HTTP (temps en millisecondes)",
+                "title": "Requêtes HTTP (évènements par seconde)",
                 "active": "Requêtes actives :",
                 "total": "Requêtes totales :",
                 "table": {
                     "code": "Code",
                     "count": "Total",
                     "mean": "Médian",
-                    "average": "Moyenne",
-                    "max": "Max"
+                    "average": "Moyenne"
                 },
                 "code": {
                     "ok": "Ok",
@@ -86,7 +85,7 @@
             "averageRemoveTime": "Temps de suppression moyen (µs)"
         },
         "datasource": {
-            "usage": "Usage du Pool de connexion",
+            "usage": "Usage",
             "title": "Statistiques du pool de connexions (temps en millisecondes)",
             "name": "Utilisation du pool",
             "count": "Total",
diff --git a/generators/server/files.js b/generators/server/files.js
index 8eeef1ccf7..e59d077736 100644
--- a/generators/server/files.js
+++ b/generators/server/files.js
@@ -842,6 +842,10 @@ const serverFiles = {
                     file: 'package/config/LoggingAspectConfiguration.java',
                     renameTo: generator => `${generator.javaDir}config/LoggingAspectConfiguration.java`
                 },
+                {
+                    file: 'package/config/MetricsConfiguration.java',
+                    renameTo: generator => `${generator.javaDir}config/MetricsConfiguration.java`
+                },
                 { file: 'package/config/WebConfigurer.java', renameTo: generator => `${generator.javaDir}config/WebConfigurer.java` }
             ]
         },
diff --git a/generators/server/templates/build.gradle.ejs b/generators/server/templates/build.gradle.ejs
index c6ec439681..9d15b3126c 100644
--- a/generators/server/templates/build.gradle.ejs
+++ b/generators/server/templates/build.gradle.ejs
@@ -246,7 +246,17 @@ dependencies {
     compile "org.springframework.boot:spring-boot-starter-cache"
     <%_ } _%>
     compile "io.dropwizard.metrics:metrics-core"
-    compile 'io.micrometer:micrometer-registry-prometheus'
+    <%_ if (['ehcache', 'infinispan'].includes(cacheProvider)) { _%>
+    compile "io.dropwizard.metrics:metrics-jcache"
+    <%_ } _%>
+    compile "io.dropwizard.metrics:metrics-json"
+    compile "io.dropwizard.metrics:metrics-jmx"
+    compile "io.dropwizard.metrics:metrics-jvm"
+    compile "io.dropwizard.metrics:metrics-servlet"
+    compile "io.dropwizard.metrics:metrics-servlets"
+    compile "io.prometheus:simpleclient"
+    compile "io.prometheus:simpleclient_dropwizard"
+    compile "io.prometheus:simpleclient_servlet"
     compile "net.logstash.logback:logstash-logback-encoder"
     compile "com.fasterxml.jackson.datatype:jackson-datatype-hppc"
     compile "com.fasterxml.jackson.datatype:jackson-datatype-jsr310"
@@ -256,6 +266,7 @@ dependencies {
     compile "com.fasterxml.jackson.core:jackson-annotations"
     compile "com.fasterxml.jackson.core:jackson-databind"
     compile "com.fasterxml.jackson.module:jackson-module-afterburner"
+    compile "com.ryantenney.metrics:metrics-spring"
     <%_ if (applicationType === 'gateway' && authenticationType === 'uaa') { _%>
     compile "org.apache.httpcomponents:httpclient"
     <%_ } _%>
diff --git a/generators/server/templates/gradle.properties.ejs b/generators/server/templates/gradle.properties.ejs
index 33dc12b845..7f1893cb5f 100644
--- a/generators/server/templates/gradle.properties.ejs
+++ b/generators/server/templates/gradle.properties.ejs
@@ -25,7 +25,7 @@ npm_version=<%= NPM_VERSION %>
 yarn_version=<%= YARN_VERSION %>
 
 # Dependency versions
-jhipster_dependencies_version=2.2.0-SNAPSHOT
+jhipster_dependencies_version=2.1.0-SNAPSHOT
 # The spring-boot version should match the one managed by
 # https://mvnrepository.com/artifact/io.github.jhipster/jhipster-dependencies/${jhipster_dependencies_version}
 spring_boot_version=2.1.1.RELEASE
diff --git a/generators/server/templates/pom.xml.ejs b/generators/server/templates/pom.xml.ejs
index 20e0a16466..e3d1a07e93 100644
--- a/generators/server/templates/pom.xml.ejs
+++ b/generators/server/templates/pom.xml.ejs
@@ -106,7 +106,7 @@
         <profile.tls />
 
         <!-- Dependency versions -->
-        <jhipster-dependencies.version>2.2.0-SNAPSHOT</jhipster-dependencies.version>
+        <jhipster-dependencies.version>2.1.0-SNAPSHOT</jhipster-dependencies.version>
         <!-- The spring-boot version should match the one managed by
         https://mvnrepository.com/artifact/io.github.jhipster/jhipster-dependencies/${jhipster-dependencies.version} -->
         <spring-boot.version>2.1.1.RELEASE</spring-boot.version>
@@ -216,6 +216,52 @@
             <artifactId>spring-boot-starter-cache</artifactId>
         </dependency>
         <%_ } _%>
+        <dependency>
+            <groupId>io.dropwizard.metrics</groupId>
+            <artifactId>metrics-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.dropwizard.metrics</groupId>
+            <artifactId>metrics-annotation</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.dropwizard.metrics</groupId>
+            <artifactId>metrics-json</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.prometheus</groupId>
+            <artifactId>simpleclient</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.prometheus</groupId>
+            <artifactId>simpleclient_dropwizard</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.prometheus</groupId>
+            <artifactId>simpleclient_servlet</artifactId>
+        </dependency>
+        <%_ if (['ehcache', 'infinispan'].includes(cacheProvider)) { _%>
+        <dependency>
+            <groupId>io.dropwizard.metrics</groupId>
+            <artifactId>metrics-jcache</artifactId>
+        </dependency>
+        <%_ } _%>
+        <dependency>
+            <groupId>io.dropwizard.metrics</groupId>
+            <artifactId>metrics-jmx</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.dropwizard.metrics</groupId>
+            <artifactId>metrics-jvm</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.dropwizard.metrics</groupId>
+            <artifactId>metrics-servlet</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.dropwizard.metrics</groupId>
+            <artifactId>metrics-servlets</artifactId>
+        </dependency>
         <%_ if (databaseType === 'sql') { _%>
         <dependency>
             <groupId>com.fasterxml.jackson.datatype</groupId>
@@ -315,6 +361,10 @@
             <artifactId>springfox-bean-validators</artifactId>
         </dependency>
         <%_ } _%>
+        <dependency>
+            <groupId>com.ryantenney.metrics</groupId>
+            <artifactId>metrics-spring</artifactId>
+        </dependency>
         <%_ if (databaseType === 'sql') { _%>
         <dependency>
             <groupId>com.zaxxer</groupId>
@@ -727,14 +777,6 @@
             <groupId>org.springframework.security</groupId>
             <artifactId>spring-security-data</artifactId>
         </dependency>
-        <dependency>
-            <groupId>io.micrometer</groupId>
-            <artifactId>micrometer-registry-prometheus</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>io.dropwizard.metrics</groupId>
-            <artifactId>metrics-core</artifactId>
-        </dependency>
         <%_ if (websocket === 'spring-websocket') { _%>
         <dependency>
             <groupId>org.springframework.security</groupId>
diff --git a/generators/server/templates/src/main/docker/cassandra/scripts/autoMigrate.sh.ejs b/generators/server/templates/src/main/docker/cassandra/scripts/autoMigrate.sh.ejs
index fed914bbec..a2b23b5577 100644
--- a/generators/server/templates/src/main/docker/cassandra/scripts/autoMigrate.sh.ejs
+++ b/generators/server/templates/src/main/docker/cassandra/scripts/autoMigrate.sh.ejs
@@ -69,7 +69,7 @@ if [ "$#" -gt 0 ]; then
     fi
     CREATE_KEYSPACE_SCRIPT_FOLDER="$(dirname $CQL_FILES_PATH)"
     SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-    EXECUTE_CQL_SCRIPT=$SCRIPT_DIR'/execute-cql.sh'
+    EXECUTE_CQL_SCRIPT=$SCRIPT_DIR'/execute-cql'
 else
     CQL_FILES_PATH="/cql/changelog/"
     EXECUTE_CQL_SCRIPT="./usr/local/bin/execute-cql"
diff --git a/generators/server/templates/src/main/java/package/config/ReactiveSecurityConfiguration.java.ejs b/generators/server/templates/src/main/java/package/config/ReactiveSecurityConfiguration.java.ejs
index 9f53b47486..5a8c307e43 100644
--- a/generators/server/templates/src/main/java/package/config/ReactiveSecurityConfiguration.java.ejs
+++ b/generators/server/templates/src/main/java/package/config/ReactiveSecurityConfiguration.java.ejs
@@ -123,7 +123,6 @@ public class SecurityConfiguration {
             .pathMatchers("/api/**").authenticated()
             .pathMatchers("/management/health").permitAll()
             .pathMatchers("/management/info").permitAll()
-            .pathMatchers("/management/prometheus").permitAll()
             .pathMatchers("/management/**").hasAuthority(AuthoritiesConstants.ADMIN);
         return http.build();
     }
diff --git a/generators/server/templates/src/main/java/package/config/WebConfigurer.java.ejs b/generators/server/templates/src/main/java/package/config/WebConfigurer.java.ejs
index 0e00cc6764..d8945062fd 100644
--- a/generators/server/templates/src/main/java/package/config/WebConfigurer.java.ejs
+++ b/generators/server/templates/src/main/java/package/config/WebConfigurer.java.ejs
@@ -18,6 +18,9 @@
 -%>
 package <%=packageName%>.config;
 
+import com.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.servlet.InstrumentedFilter;
+import com.codahale.metrics.servlets.MetricsServlet;
 <%_ if (reactive) { _%>
 import com.fasterxml.jackson.databind.ObjectMapper;
 <%_ } _%>
@@ -89,13 +92,15 @@ public class WebConfigurer implements ServletContextInitializer, WebServerFactor
 
     private final JHipsterProperties jHipsterProperties;
 
+    private MetricRegistry metricRegistry;
+
     public WebConfigurer(Environment env, JHipsterProperties jHipsterProperties) {
 
         this.env = env;
         this.jHipsterProperties = jHipsterProperties;
     }
 
-    <%_
+    <%_ 
         // TODO: remove when this is supported in spring-data / spring-boot
         if (reactive) { _%>
     @Override
@@ -111,6 +116,7 @@ public class WebConfigurer implements ServletContextInitializer, WebServerFactor
             log.info("Web application configuration, using profiles: {}", (Object[]) env.getActiveProfiles());
         }
         EnumSet<DispatcherType> disps = EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.ASYNC);
+        initMetrics(servletContext, disps);
         <%_ if (!skipClient) { _%>
         if (env.acceptsProfiles(Profiles.of(JHipsterConstants.SPRING_PROFILE_PRODUCTION))) {
             initCachingHttpHeadersFilter(servletContext, disps);
@@ -212,6 +218,32 @@ public class WebConfigurer implements ServletContextInitializer, WebServerFactor
     }
     <%_ } _%>
 
+    /**
+     * Initializes Metrics.
+     */
+    private void initMetrics(ServletContext servletContext, EnumSet<DispatcherType> disps) {
+        log.debug("Initializing Metrics registries");
+        servletContext.setAttribute(InstrumentedFilter.REGISTRY_ATTRIBUTE,
+            metricRegistry);
+        servletContext.setAttribute(MetricsServlet.METRICS_REGISTRY,
+            metricRegistry);
+
+        log.debug("Registering Metrics Filter");
+        FilterRegistration.Dynamic metricsFilter = servletContext.addFilter("webappMetricsFilter",
+            new InstrumentedFilter());
+
+        metricsFilter.addMappingForUrlPatterns(disps, true, "/*");
+        metricsFilter.setAsyncSupported(true);
+
+        log.debug("Registering Metrics Servlet");
+        ServletRegistration.Dynamic metricsAdminServlet =
+            servletContext.addServlet("metricsServlet", new MetricsServlet());
+
+        metricsAdminServlet.addMapping("/management/metrics/*");
+        metricsAdminServlet.setAsyncSupported(true);
+        metricsAdminServlet.setLoadOnStartup(2);
+    }
+
     @Bean
     public Cors<% if (reactive) { %>Web<% } %>Filter corsFilter() {
         UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
@@ -253,4 +285,8 @@ public class WebConfigurer implements ServletContextInitializer, WebServerFactor
     }
     <%_ } _%>
 
+    @Autowired(required = false)
+    public void setMetricRegistry(MetricRegistry metricRegistry) {
+        this.metricRegistry = metricRegistry;
+    }
 }
diff --git a/generators/server/templates/src/main/java/package/config/cassandra/CassandraConfiguration.java.ejs b/generators/server/templates/src/main/java/package/config/cassandra/CassandraConfiguration.java.ejs
index 8870711b57..a39a25cf12 100644
--- a/generators/server/templates/src/main/java/package/config/cassandra/CassandraConfiguration.java.ejs
+++ b/generators/server/templates/src/main/java/package/config/cassandra/CassandraConfiguration.java.ejs
@@ -68,7 +68,7 @@ public class CassandraConfiguration implements InitializingBean {
     private Cluster cluster;
 
     @Override
-    public void afterPropertiesSet() {
+    public void afterPropertiesSet() throws Exception {
         TupleType tupleType = cluster.getMetadata()
             .newTupleType(DataType.timestamp(), DataType.varchar());
 
@@ -77,7 +77,10 @@ public class CassandraConfiguration implements InitializingBean {
             .register(InstantCodec.instance)
             .register(new ZonedDateTimeCodec(tupleType));
 
-        cluster.init();
+        if (metricRegistry != null) {
+            cluster.init();
+            metricRegistry.registerAll(cluster.getMetrics().getRegistry());
+        }
     }
 
     @Bean
@@ -122,9 +125,7 @@ public class CassandraConfiguration implements InitializingBean {
     ClusterBuilderCustomizer clusterBuilderCustomizer(CassandraProperties properties) {
         return builder -> builder
             .withProtocolVersion(protocolVersion)
-            .withPort(getPort(properties))
-            .withoutJMXReporting()
-            .withoutMetrics();
+            .withPort(getPort(properties));
     }
 
     protected int getPort(CassandraProperties properties) {
diff --git a/generators/server/templates/src/main/java/package/web/rest/AccountResource.java.ejs b/generators/server/templates/src/main/java/package/web/rest/AccountResource.java.ejs
index 2bb3ecf6e4..2c0ea488b1 100644
--- a/generators/server/templates/src/main/java/package/web/rest/AccountResource.java.ejs
+++ b/generators/server/templates/src/main/java/package/web/rest/AccountResource.java.ejs
@@ -23,6 +23,7 @@ import <%=packageName%>.service.UserService;
 import <%=packageName%>.service.dto.UserDTO;
 import <%=packageName%>.web.rest.errors.InternalServerErrorException;
 
+import com.codahale.metrics.annotation.Timed;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.security.oauth2.provider.OAuth2Authentication;
@@ -55,6 +56,7 @@ public class AccountResource {
      * @return the login if the user is authenticated
      */
     @GetMapping("/authenticate")
+    @Timed
     public String isAuthenticated(HttpServletRequest request) {
         log.debug("REST request to check if the current user is authenticated");
         return request.getRemoteUser();
@@ -68,6 +70,7 @@ public class AccountResource {
      * @throws InternalServerErrorException 500 (Internal Server Error) if the user couldn't be returned
      */
     @GetMapping("/account")
+    @Timed
     @SuppressWarnings("unchecked")
     public UserDTO getAccount(Principal principal) {
         if (principal != null) {
@@ -85,6 +88,7 @@ public class AccountResource {
     }
 }
 <%_ } else { _%>
+import com.codahale.metrics.annotation.Timed;
 
 <%_ if (authenticationType === 'session') { _%>
 import <%=packageName%>.domain.PersistentToken;
@@ -166,6 +170,7 @@ public class AccountResource {
      * @throws LoginAlreadyUsedException 400 (Bad Request) if the login is already used
      */
     @PostMapping("/register")
+    @Timed
     @ResponseStatus(HttpStatus.CREATED)
     public <% if (reactive) { %>Mono<Void><% } else { %>void<% } %> registerAccount(@Valid @RequestBody ManagedUserVM managedUserVM) {
         if (!checkPasswordLength(managedUserVM.getPassword())) {
@@ -188,6 +193,7 @@ public class AccountResource {
      * @throws RuntimeException 500 (Internal Server Error) if the user couldn't be activated
      */
     @GetMapping("/activate")
+    @Timed
     public <% if (reactive) { %>Mono<Void><% } else { %>void<% } %> activateAccount(@RequestParam(value = "key") String key) {
         <%_ if (!reactive) { _%>
         Optional<User> user = userService.activateRegistration(key);
@@ -208,6 +214,7 @@ public class AccountResource {
      * @return the login if the user is authenticated
      */
     @GetMapping("/authenticate")
+    @Timed
     <%_ if (!reactive) { _%>
     public String isAuthenticated(HttpServletRequest request) {
         log.debug("REST request to check if the current user is authenticated");
@@ -226,6 +233,7 @@ public class AccountResource {
      * @throws RuntimeException 500 (Internal Server Error) if the user couldn't be returned
      */
     @GetMapping("/account")
+    @Timed
     public <% if (reactive) { %>Mono<UserDTO><% } else { %>UserDTO<% } %> getAccount() {
         return userService.getUserWithAuthorities()
             .map(UserDTO::new)
@@ -244,6 +252,7 @@ public class AccountResource {
      * @throws RuntimeException 500 (Internal Server Error) if the user login wasn't found
      */
     @PostMapping("/account")
+    @Timed
     <%_ if (!reactive) { _%>
     public void saveAccount(@Valid @RequestBody UserDTO userDTO) {
         String userLogin = SecurityUtils.getCurrentUserLogin().orElseThrow(() -> new InternalServerErrorException("Current user login not found"));
@@ -283,6 +292,7 @@ public class AccountResource {
      * @throws InvalidPasswordException 400 (Bad Request) if the new password is incorrect
      */
     @PostMapping(path = "/account/change-password")
+    @Timed
     public <% if (reactive) { %>Mono<Void><% } else { %>void<% } %> changePassword(@RequestBody PasswordChangeDTO passwordChangeDto) {
         if (!checkPasswordLength(passwordChangeDto.getNewPassword())) {
             throw new InvalidPasswordException();
@@ -297,6 +307,7 @@ public class AccountResource {
      * @throws RuntimeException 500 (Internal Server Error) if the current open sessions couldn't be retrieved
      */
     @GetMapping("/account/sessions")
+    @Timed
     public List<PersistentToken> getCurrentSessions() {
         return persistentTokenRepository.findByUser(
             userRepository.findOneByLogin(SecurityUtils.getCurrentUserLogin()
@@ -322,6 +333,7 @@ public class AccountResource {
      * @throws UnsupportedEncodingException if the series couldnt be URL decoded
      */
     @DeleteMapping("/account/sessions/{series}")
+    @Timed
     public void invalidateSession(@PathVariable String series) throws UnsupportedEncodingException {
         String decodedSeries = URLDecoder.decode(series, "UTF-8");
         SecurityUtils.getCurrentUserLogin()
@@ -342,6 +354,7 @@ public class AccountResource {
      * @throws EmailNotFoundException 400 (Bad Request) if the email address is not registered
      */
     @PostMapping(path = "/account/reset-password/init")
+    @Timed
     <%_ if (!reactive) { _%>
     public void requestPasswordReset(@RequestBody String mail) {
        mailService.sendPasswordResetMail(
@@ -365,6 +378,7 @@ public class AccountResource {
      * @throws RuntimeException 500 (Internal Server Error) if the password could not be reset
      */
     @PostMapping(path = "/account/reset-password/finish")
+    @Timed
     public <% if (reactive) { %>Mono<Void><% } else { %>void<% } %> finishPasswordReset(@RequestBody KeyAndPasswordVM keyAndPassword) {
         if (!checkPasswordLength(keyAndPassword.getNewPassword())) {
             throw new InvalidPasswordException();
diff --git a/generators/server/templates/src/main/java/package/web/rest/AuthResource.java.ejs b/generators/server/templates/src/main/java/package/web/rest/AuthResource.java.ejs
index fd8237ebfb..7336700179 100755
--- a/generators/server/templates/src/main/java/package/web/rest/AuthResource.java.ejs
+++ b/generators/server/templates/src/main/java/package/web/rest/AuthResource.java.ejs
@@ -18,6 +18,7 @@
 -%>
 package <%=packageName%>.web.rest;
 
+import com.codahale.metrics.annotation.Timed;
 import <%=packageName%>.security.oauth2.OAuth2AuthenticationService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -62,6 +63,7 @@ public class AuthResource {
      */
     @RequestMapping(value = "/login", method = RequestMethod.POST, consumes = MediaType
         .APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
+    @Timed
     public ResponseEntity<OAuth2AccessToken> authenticate(HttpServletRequest request, HttpServletResponse response, @RequestBody
         Map<String, String> params) {
         return authenticationService.authenticate(request, response, params);
@@ -75,6 +77,7 @@ public class AuthResource {
      * @return an empty response entity.
      */
     @RequestMapping(value = "/logout", method = RequestMethod.POST)
+    @Timed
     public ResponseEntity<?> logout(HttpServletRequest request, HttpServletResponse response) {
         log.info("logging out user {}", SecurityContextHolder.getContext().getAuthentication().getName());
         authenticationService.logout(request, response);
diff --git a/generators/server/templates/src/main/java/package/web/rest/GatewayResource.java.ejs b/generators/server/templates/src/main/java/package/web/rest/GatewayResource.java.ejs
index 15997d8452..8249694c74 100644
--- a/generators/server/templates/src/main/java/package/web/rest/GatewayResource.java.ejs
+++ b/generators/server/templates/src/main/java/package/web/rest/GatewayResource.java.ejs
@@ -31,6 +31,8 @@ import org.springframework.security.access.annotation.Secured;
 import <%=packageName%>.security.AuthoritiesConstants;
 import org.springframework.web.bind.annotation.*;
 
+import com.codahale.metrics.annotation.Timed;
+
 /**
  * REST controller for managing Gateway configuration.
  */
@@ -53,6 +55,7 @@ public class GatewayResource {
      * @return the ResponseEntity with status 200 (OK) and with body the list of routes
      */
     @GetMapping("/routes")
+    @Timed
     @Secured(AuthoritiesConstants.ADMIN)
     public ResponseEntity<List<RouteVM>> activeRoutes() {
         List<Route> routes = routeLocator.getRoutes();
diff --git a/generators/server/templates/src/main/java/package/web/rest/LogsResource.java.ejs b/generators/server/templates/src/main/java/package/web/rest/LogsResource.java.ejs
index f3367baacf..7a8bc81654 100644
--- a/generators/server/templates/src/main/java/package/web/rest/LogsResource.java.ejs
+++ b/generators/server/templates/src/main/java/package/web/rest/LogsResource.java.ejs
@@ -22,6 +22,7 @@ import <%=packageName%>.web.rest.vm.LoggerVM;
 
 import ch.qos.logback.classic.Level;
 import ch.qos.logback.classic.LoggerContext;
+import com.codahale.metrics.annotation.Timed;
 import org.slf4j.LoggerFactory;
 import org.springframework.http.HttpStatus;
 import org.springframework.web.bind.annotation.*;
@@ -41,6 +42,7 @@ import java.util.stream.Collectors;
 public class LogsResource {
 
     @GetMapping("/logs")
+    @Timed
     public <% if (reactive) { %>Flux<% } else { %>List<% } %><LoggerVM> getList() {
         LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
         <%_ if (reactive) { _%>
@@ -56,6 +58,7 @@ public class LogsResource {
 
     @PutMapping("/logs")
     @ResponseStatus(HttpStatus.NO_CONTENT)
+    @Timed
     public void changeLevel(@RequestBody LoggerVM jsonLogger) {
         LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
         context.getLogger(jsonLogger.getName()).setLevel(Level.valueOf(jsonLogger.getLevel()));
diff --git a/generators/server/templates/src/main/java/package/web/rest/UserJWTController.java.ejs b/generators/server/templates/src/main/java/package/web/rest/UserJWTController.java.ejs
index a758b1f40f..7dc9f5f590 100644
--- a/generators/server/templates/src/main/java/package/web/rest/UserJWTController.java.ejs
+++ b/generators/server/templates/src/main/java/package/web/rest/UserJWTController.java.ejs
@@ -22,6 +22,7 @@ import <%= packageName %>.security.jwt.JWTFilter;
 import <%= packageName %>.security.jwt.TokenProvider;
 import <%= packageName %>.web.rest.vm.LoginVM;
 
+import com.codahale.metrics.annotation.Timed;
 import com.fasterxml.jackson.annotation.JsonProperty;
 
 import org.springframework.http.HttpHeaders;
@@ -60,6 +61,7 @@ public class UserJWTController {
     }
 
     @PostMapping("/authenticate")
+    @Timed
     <%_ if (!reactive) { _%>
     public ResponseEntity<JWTToken> authorize(@Valid @RequestBody LoginVM loginVM) {
 
diff --git a/generators/server/templates/src/main/java/package/web/rest/UserResource.java.ejs b/generators/server/templates/src/main/java/package/web/rest/UserResource.java.ejs
index cf6f551811..5df7aeaaba 100644
--- a/generators/server/templates/src/main/java/package/web/rest/UserResource.java.ejs
+++ b/generators/server/templates/src/main/java/package/web/rest/UserResource.java.ejs
@@ -43,6 +43,7 @@ import <%=packageName%>.web.rest.util.HeaderUtil;
 <%_ if (databaseType === 'sql' || databaseType === 'mongodb' || databaseType === 'couchbase') { _%>
 import <%=packageName%>.web.rest.util.PaginationUtil;
 <%_ } _%>
+import com.codahale.metrics.annotation.Timed;
 <%_ if (!reactive) { _%>
 import io.github.jhipster.web.util.ResponseUtil;
 <%_ } _%>
@@ -159,6 +160,7 @@ public class UserResource {
      * @throws BadRequestAlertException 400 (Bad Request) if the login or email is already in use
      */
     @PostMapping("/users")
+    @Timed
     @PreAuthorize("hasRole(\"" + AuthoritiesConstants.ADMIN + "\")")
     public <% if (reactive) { %>Mono<ResponseEntity<User>><% } else { %>ResponseEntity<User><% } %> createUser(@Valid @RequestBody UserDTO userDTO)<% if (!reactive) { %> throws URISyntaxException<% } %> {
         log.debug("REST request to save User : {}", userDTO);
@@ -217,6 +219,7 @@ public class UserResource {
      * @throws LoginAlreadyUsedException 400 (Bad Request) if the login is already in use
      */
     @PutMapping("/users")
+    @Timed
     @PreAuthorize("hasRole(\"" + AuthoritiesConstants.ADMIN + "\")")
     <%_ if (!reactive) { _%>
     public ResponseEntity<UserDTO> updateUser(@Valid @RequestBody UserDTO userDTO) {
@@ -269,6 +272,7 @@ public class UserResource {
      * @return the ResponseEntity with status 200 (OK) and with body all users
      */
     @GetMapping("/users")
+    @Timed
     <%_ if (databaseType === 'sql' || databaseType === 'mongodb' || databaseType === 'couchbase') { _%>
         <%_ if (!reactive) { _%>
     public ResponseEntity<List<UserDTO>> getAllUsers(Pageable pageable) {
@@ -288,6 +292,7 @@ public class UserResource {
      * @return a string list of the all of the roles
      */
     @GetMapping("/users/authorities")
+    @Timed
     @PreAuthorize("hasRole(\"" + AuthoritiesConstants.ADMIN + "\")")
     public <% if (reactive) { %>Mono<List<String>><% } else { %>List<String><% } %> getAuthorities() {
         return userService.getAuthorities()<% if (reactive) { %>.collectList()<% } %>;
@@ -306,6 +311,7 @@ public class UserResource {
      * @return the ResponseEntity with status 200 (OK) and with body the "login" user, or with status 404 (Not Found)
      */
     @GetMapping("/users/{login:" + Constants.LOGIN_REGEX + "}")
+    @Timed
     <%_ if (!reactive) { _%>
     public ResponseEntity<UserDTO> getUser(@PathVariable String login) {
         log.debug("REST request to get User : {}", login);
@@ -329,6 +335,7 @@ public class UserResource {
      * @return the ResponseEntity with status 200 (OK)
      */
     @DeleteMapping("/users/{login:" + Constants.LOGIN_REGEX + "}")
+    @Timed
     @PreAuthorize("hasRole(\"" + AuthoritiesConstants.ADMIN + "\")")
     <%_ if (!reactive) { _%>
     public ResponseEntity<Void> deleteUser(@PathVariable String login) {
@@ -353,6 +360,7 @@ public class UserResource {
      * @return the result of the search
      */
     @GetMapping("/_search/users/{query}")
+    @Timed
     public List<User> search(@PathVariable String query) {
         return StreamSupport
             .stream(userSearchRepository.search(queryStringQuery(query)).spliterator(), false)
diff --git a/generators/server/templates/src/main/resources/config/application-dev.yml.ejs b/generators/server/templates/src/main/resources/config/application-dev.yml.ejs
index 729e378589..e705c18ed2 100644
--- a/generators/server/templates/src/main/resources/config/application-dev.yml.ejs
+++ b/generators/server/templates/src/main/resources/config/application-dev.yml.ejs
@@ -120,7 +120,6 @@ spring:
         password:
         <%_ } _%>
         hikari:
-            poolName: Hikari
             auto-commit: false
         <%_ if (devDatabaseType === 'mysql' || devDatabaseType === 'mariadb' || devDatabaseType === 'mssql') { _%>
             data-source-properties:
@@ -350,8 +349,12 @@ jhipster:
     mail: # specific JHipster mail property, for standard properties see MailProperties
         from: <%= baseName %>@localhost
         base-url: http://127.0.0.1:<%= applicationType !== 'uaa' ? serverPort : 8080 %>
-    metrics:
-        logs: # Reports metrics in the logs
+    metrics: # DropWizard Metrics configuration, used by MetricsConfiguration
+        jmx:
+            enabled: false
+        prometheus:
+            enabled: false #expose metrics via prometheus
+        logs: # Reports Dropwizard metrics in the logs
             enabled: false
             report-frequency: 60 # in seconds
     logging:
diff --git a/generators/server/templates/src/main/resources/config/application-prod.yml.ejs b/generators/server/templates/src/main/resources/config/application-prod.yml.ejs
index 36d36da956..156776a912 100644
--- a/generators/server/templates/src/main/resources/config/application-prod.yml.ejs
+++ b/generators/server/templates/src/main/resources/config/application-prod.yml.ejs
@@ -97,7 +97,6 @@ spring:
         password: oracle
         <%_ } _%>
         hikari:
-            poolName: Hikari
             auto-commit: false
         <%_ if (prodDatabaseType === 'mysql' || prodDatabaseType === 'mariadb' || prodDatabaseType === 'mssql') { _%>
             data-source-properties:
@@ -135,7 +134,7 @@ spring:
             hibernate.connection.provider_disables_autocommit: true
             hibernate.cache.use_second_level_cache: <% if (enableHibernateCache) { %>true<% } else { %>false<% } %>
             hibernate.cache.use_query_cache: false
-            hibernate.generate_statistics: true
+            hibernate.generate_statistics: false
             <%_ if (enableHibernateCache) { _%>
                 <%_ if (cacheProvider === 'hazelcast') { _%>
             hibernate.cache.region.factory_class: com.hazelcast.hibernate.HazelcastCacheRegionFactory
@@ -330,8 +329,12 @@ jhipster:
     mail: # specific JHipster mail property, for standard properties see MailProperties
         from: <%= baseName %>@localhost
         base-url: http://my-server-url-to-change # Modify according to your server's URL
-    metrics:
-        logs: # Reports metrics in the logs
+    metrics: # DropWizard Metrics configuration, used by MetricsConfiguration
+        jmx:
+            enabled: false
+        prometheus:
+            enabled: false #expose metrics via prometheus
+        logs: # Reports Dropwizard metrics in the logs
             enabled: false
             report-frequency: 60 # in seconds
     logging:
diff --git a/generators/server/templates/src/main/resources/config/application.yml.ejs b/generators/server/templates/src/main/resources/config/application.yml.ejs
index 1976bc2226..83fce8853a 100644
--- a/generators/server/templates/src/main/resources/config/application.yml.ejs
+++ b/generators/server/templates/src/main/resources/config/application.yml.ejs
@@ -111,12 +111,10 @@ management:
         web:
             base-path: /management
             exposure:
-                include: ["configprops", "env", "health", "info", "threaddump", "logfile", "jhi-metrics", "prometheus" ]
+                include: ["configprops", "env", "health", "info", "threaddump", "logfile" ]
     endpoint:
         health:
             show-details: when-authorized
-        jhi-metrics:
-            enabled: true
     info:
         git:
             mode: full
@@ -124,32 +122,8 @@ management:
         mail:
             enabled: false # When using the MailService, configure an SMTP server and set this to true
     metrics:
-        export:
-            # Prometheus is the default metrics backend
-            prometheus:
-                enabled: true
-                step: 60
-        binders:
-            jvm:
-                enabled: true
-            processor:
-                enabled: true
-            uptime:
-                enabled: true
-            logback:
-                enabled: true
-            files:
-                enabled: true
-            integration:
-                enabled: true
-        distribution:
-            percentiles-histogram:
-                all: true
-            percentiles:
-                all: 0, 0.5, 0.75, 0.95, 0.99, 1.0
-        web:
-            server:
-                auto-time-requests: true
+        enable:
+            all: false # http://micrometer.io/ is disabled by default, as we use http://metrics.dropwizard.io/ instead
 
 spring:
     <%_ if (searchEngine === 'elasticsearch') { _%>
diff --git a/generators/server/templates/src/main/resources/logback-spring.xml.ejs b/generators/server/templates/src/main/resources/logback-spring.xml.ejs
index 6ace5a5ebd..9745ad4c75 100644
--- a/generators/server/templates/src/main/resources/logback-spring.xml.ejs
+++ b/generators/server/templates/src/main/resources/logback-spring.xml.ejs
@@ -53,7 +53,7 @@
     <logger name="javax.management.remote" level="WARN"/>
     <logger name="javax.xml.bind" level="WARN"/>
     <logger name="ch.qos.logback" level="WARN"/>
-    <% if (databaseType === 'cassandra') { %>
+    <logger name="com.codahale.metrics" level="WARN"/><% if (databaseType === 'cassandra') { %>
     <logger name="com.datastax" level="WARN"/><% } %>
     <%_ if (cacheProvider === 'hazelcast') { _%>
     <logger name="com.hazelcast" level="INFO"/>


Test patch:
diff --git a/generators/client/templates/angular/src/test/javascript/spec/app/admin/metrics/metrics.component.spec.ts.ejs b/generators/client/templates/angular/src/test/javascript/spec/app/admin/metrics/metrics.component.spec.ts.ejs
index 3275464bb8..e0ec93946e 100644
--- a/generators/client/templates/angular/src/test/javascript/spec/app/admin/metrics/metrics.component.spec.ts.ejs
+++ b/generators/client/templates/angular/src/test/javascript/spec/app/admin/metrics/metrics.component.spec.ts.ejs
@@ -67,6 +67,15 @@ describe('Component Tests', () => {
 
                 // THEN
                 expect(service.getMetrics).toHaveBeenCalled();
+                expect(comp.servicesStats).toEqual({ service: 'test' });
+                expect(comp.cachesStats).toEqual({ jcache: { name: 17, value: 2 } });
+            });
+        });
+
+        describe('isNan', () => {
+            it('should return if a variable is NaN', () => {
+                expect(comp.filterNaN(1)).toBe(1);
+                expect(comp.filterNaN('test')).toBe(0);
             });
         });
     });
diff --git a/generators/client/templates/angular/src/test/javascript/spec/app/admin/metrics/metrics.service.spec.ts.ejs b/generators/client/templates/angular/src/test/javascript/spec/app/admin/metrics/metrics.service.spec.ts.ejs
index d971c3a184..3da4c0d147 100644
--- a/generators/client/templates/angular/src/test/javascript/spec/app/admin/metrics/metrics.service.spec.ts.ejs
+++ b/generators/client/templates/angular/src/test/javascript/spec/app/admin/metrics/metrics.service.spec.ts.ejs
@@ -45,7 +45,7 @@ describe('Service Tests', () => {
                 service.getMetrics().subscribe(() => {});
 
                 const req = httpMock.expectOne({ method: 'GET' });
-                const resourceUrl = SERVER_API_URL + 'management/jhi-metrics';
+                const resourceUrl = SERVER_API_URL + 'management/metrics';
                 expect(req.request.url).toEqual(resourceUrl);
             });
 
diff --git a/generators/server/templates/src/test/java/package/config/WebConfigurerTest.java.ejs b/generators/server/templates/src/test/java/package/config/WebConfigurerTest.java.ejs
index 3df8727e20..63baa9e47b 100644
--- a/generators/server/templates/src/test/java/package/config/WebConfigurerTest.java.ejs
+++ b/generators/server/templates/src/test/java/package/config/WebConfigurerTest.java.ejs
@@ -18,6 +18,9 @@
 -%>
 package <%= packageName %>.config;
 
+import com.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.servlet.InstrumentedFilter;
+import com.codahale.metrics.servlets.MetricsServlet;
 import io.github.jhipster.config.JHipsterConstants;
 import io.github.jhipster.config.JHipsterProperties;
 <%_ if (!skipClient) { _%>
@@ -70,6 +73,8 @@ public class WebConfigurerTest {
 
     private JHipsterProperties props;
 
+    private MetricRegistry metricRegistry;
+
     @Before
     public void setup() {
         servletContext = spy(new MockServletContext());
@@ -82,6 +87,8 @@ public class WebConfigurerTest {
         props = new JHipsterProperties();
 
         webConfigurer = new WebConfigurer(env, props);
+        metricRegistry = new MetricRegistry();
+        webConfigurer.setMetricRegistry(metricRegistry);
     }
 
     @Test
@@ -89,6 +96,10 @@ public class WebConfigurerTest {
         env.setActiveProfiles(JHipsterConstants.SPRING_PROFILE_PRODUCTION);
         webConfigurer.onStartup(servletContext);
 
+        assertThat(servletContext.getAttribute(InstrumentedFilter.REGISTRY_ATTRIBUTE)).isEqualTo(metricRegistry);
+        assertThat(servletContext.getAttribute(MetricsServlet.METRICS_REGISTRY)).isEqualTo(metricRegistry);
+        verify(servletContext).addFilter(eq("webappMetricsFilter"), any(InstrumentedFilter.class));
+        verify(servletContext).addServlet(eq("metricsServlet"), any(MetricsServlet.class));
         <%_ if (!skipClient) { _%>
         verify(servletContext).addFilter(eq("cachingHttpHeadersFilter"), any(CachingHttpHeadersFilter.class));
         <%_ } _%>
@@ -102,6 +113,10 @@ public class WebConfigurerTest {
         env.setActiveProfiles(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT);
         webConfigurer.onStartup(servletContext);
 
+        assertThat(servletContext.getAttribute(InstrumentedFilter.REGISTRY_ATTRIBUTE)).isEqualTo(metricRegistry);
+        assertThat(servletContext.getAttribute(MetricsServlet.METRICS_REGISTRY)).isEqualTo(metricRegistry);
+        verify(servletContext).addFilter(eq("webappMetricsFilter"), any(InstrumentedFilter.class));
+        verify(servletContext).addServlet(eq("metricsServlet"), any(MetricsServlet.class));
         <%_ if (!skipClient) { _%>
         verify(servletContext, never()).addFilter(eq("cachingHttpHeadersFilter"), any(CachingHttpHeadersFilter.class));
         <%_ } _%>
diff --git a/generators/server/templates/src/test/resources/config/application.yml.ejs b/generators/server/templates/src/test/resources/config/application.yml.ejs
index db8613896d..8f7c1820cb 100644
--- a/generators/server/templates/src/test/resources/config/application.yml.ejs
+++ b/generators/server/templates/src/test/resources/config/application.yml.ejs
@@ -78,7 +78,7 @@ spring:
             hibernate.connection.provider_disables_autocommit: true
             hibernate.cache.use_second_level_cache: false
             hibernate.cache.use_query_cache: false
-            hibernate.generate_statistics: false
+            hibernate.generate_statistics: true
             hibernate.hbm2ddl.auto: validate
             hibernate.jdbc.time_zone: UTC
     <%_ } _%>
@@ -201,8 +201,9 @@ jhipster:
             # security key (this key should be unique for your application, and kept secret)
             key: <%= rememberMeKey %>
 <%_ } _%>
-    metrics:
-        logs: # Reports metrics in the logs
+    metrics: # DropWizard Metrics configuration, used by MetricsConfiguration
+        jmx.enabled: true
+        logs: # Reports Dropwizard metrics in the logs
             enabled: true
             report-frequency: 60 # in seconds
 
diff --git a/generators/server/templates/src/test/resources/logback.xml.ejs b/generators/server/templates/src/test/resources/logback.xml.ejs
index 7c14b129f0..c3232b0361 100644
--- a/generators/server/templates/src/test/resources/logback.xml.ejs
+++ b/generators/server/templates/src/test/resources/logback.xml.ejs
@@ -33,6 +33,7 @@
     <logger name="javax.mail" level="WARN"/>
     <logger name="javax.xml.bind" level="WARN"/>
     <logger name="ch.qos.logback" level="WARN"/>
+    <logger name="com.codahale.metrics" level="WARN"/>
     <%_ if (databaseType === 'cassandra') { _%>
     <logger name="com.datastax" level="WARN"/>
     <%_ } _%>
diff --git a/test/templates/ci-cd/maven-ngx-yarn/pom.xml b/test/templates/ci-cd/maven-ngx-yarn/pom.xml
index a0ec375ad5..3d1ef678fd 100644
--- a/test/templates/ci-cd/maven-ngx-yarn/pom.xml
+++ b/test/templates/ci-cd/maven-ngx-yarn/pom.xml
@@ -32,7 +32,7 @@
     </pluginRepositories>
 
     <!-- jhipster-needle-distribution-management -->
-
+    
     <properties>
         <!-- Build properties -->
         <maven.version>3.0.0</maven.version>
@@ -137,6 +137,34 @@
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-cache</artifactId>
         </dependency>
+        <dependency>
+            <groupId>io.dropwizard.metrics</groupId>
+            <artifactId>metrics-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.dropwizard.metrics</groupId>
+            <artifactId>metrics-annotation</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.dropwizard.metrics</groupId>
+            <artifactId>metrics-json</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.dropwizard.metrics</groupId>
+            <artifactId>metrics-jcache</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.dropwizard.metrics</groupId>
+            <artifactId>metrics-jvm</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.dropwizard.metrics</groupId>
+            <artifactId>metrics-servlet</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.dropwizard.metrics</groupId>
+            <artifactId>metrics-servlets</artifactId>
+        </dependency>
         <dependency>
             <groupId>com.fasterxml.jackson.datatype</groupId>
             <artifactId>jackson-datatype-hibernate5</artifactId>
diff --git a/test/utils/expected-files.js b/test/utils/expected-files.js
index 7f0c960a9b..4e58dd66c2 100644
--- a/test/utils/expected-files.js
+++ b/test/utils/expected-files.js
@@ -173,6 +173,7 @@ const expectedFiles = {
         `${SERVER_MAIN_SRC_DIR}com/mycompany/myapp/config/JacksonConfiguration.java`,
         `${SERVER_MAIN_SRC_DIR}com/mycompany/myapp/config/LocaleConfiguration.java`,
         `${SERVER_MAIN_SRC_DIR}com/mycompany/myapp/config/LoggingAspectConfiguration.java`,
+        `${SERVER_MAIN_SRC_DIR}com/mycompany/myapp/config/MetricsConfiguration.java`,
         `${SERVER_MAIN_SRC_DIR}com/mycompany/myapp/config/SecurityConfiguration.java`,
         `${SERVER_MAIN_SRC_DIR}com/mycompany/myapp/config/WebConfigurer.java`,
         `${SERVER_MAIN_SRC_DIR}com/mycompany/myapp/config/audit/package-info.java`,
@@ -363,6 +364,8 @@ const expectedFiles = {
         `${CLIENT_MAIN_SRC_DIR}app/admin/logs/logs.component.ts`,
         `${CLIENT_MAIN_SRC_DIR}app/admin/logs/logs.route.ts`,
         `${CLIENT_MAIN_SRC_DIR}app/admin/logs/logs.service.ts`,
+        `${CLIENT_MAIN_SRC_DIR}app/admin/metrics/metrics-modal.component.html`,
+        `${CLIENT_MAIN_SRC_DIR}app/admin/metrics/metrics-modal.component.ts`,
         `${CLIENT_MAIN_SRC_DIR}app/admin/metrics/metrics.component.html`,
         `${CLIENT_MAIN_SRC_DIR}app/admin/metrics/metrics.component.ts`,
         `${CLIENT_MAIN_SRC_DIR}app/admin/metrics/metrics.route.ts`,
@@ -478,6 +481,7 @@ const expectedFiles = {
         `${CLIENT_TEST_SRC_DIR}spec/app/admin/logs/logs.service.spec.ts`,
         `${CLIENT_TEST_SRC_DIR}spec/app/admin/metrics/metrics.component.spec.ts`,
         `${CLIENT_TEST_SRC_DIR}spec/app/admin/metrics/metrics.service.spec.ts`,
+        `${CLIENT_TEST_SRC_DIR}spec/app/admin/metrics/metrics-modal.component.spec.ts`,
         `${CLIENT_TEST_SRC_DIR}spec/app/core/user/account.service.spec.ts`,
         `${CLIENT_TEST_SRC_DIR}spec/app/shared/alert/alert-error.component.spec.ts`,
         `${CLIENT_TEST_SRC_DIR}spec/app/shared/login/login.component.spec.ts`,