Independent metric: Total workspace count (#16640)

Independent metric: Total workspace count 

Signed-off-by: Sergii Kabashniuk <skabashniuk@redhat.com>
7.20.x
Sergii Kabashniuk 2020-04-20 14:13:52 +02:00 committed by GitHub
parent 7a6c83b19f
commit af4465f04e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 259 additions and 105 deletions

View File

@ -74,7 +74,7 @@ objects:
deploymentconfig: grafana
spec:
containers:
- image: grafana/grafana
- image: grafana/grafana:6.6.2
imagePullPolicy: Always
name: grafana
ports:

View File

@ -3608,7 +3608,7 @@ data:
"version": 1
}
che-workspaces.json: |-
{
{
"annotations": {
"list": [
{
@ -3625,8 +3625,7 @@ data:
"editable": true,
"gnetId": null,
"graphTooltip": 1,
"id": 2,
"iteration": 1574014597638,
"iteration": 1587125836872,
"links": [],
"panels": [
{
@ -3817,98 +3816,6 @@ data:
],
"valueName": "current"
},
{
"aliasColors": {},
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": "${datasource}",
"fill": 1,
"fillGradient": 0,
"gridPos": {
"h": 5,
"w": 6,
"x": 12,
"y": 17
},
"hiddenSeries": false,
"id": 110,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"nullPointMode": "null",
"options": {
"dataLinks": []
},
"percentage": false,
"pointradius": 2,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"expr": "sum(che_workspace_starting_attempts_total)",
"legendFormat": "Workspace start attempts",
"refId": "A"
},
{
"expr": "che_workspace_starting_attempts_total{debug='true'}",
"legendFormat": "Workspace start attempts in start-debug mode",
"refId": "B"
}
],
"thresholds": [],
"timeFrom": null,
"timeRegions": [],
"timeShift": null,
"title": "Workspace start attempts",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"buckets": null,
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": 0,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": 0,
"show": true
}
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"collapsed": false,
"datasource": "$datasource",
@ -3938,6 +3845,7 @@ data:
"x": 0,
"y": 7
},
"hiddenSeries": false,
"id": 36,
"interval": "",
"legend": {
@ -4037,6 +3945,7 @@ data:
"x": 6,
"y": 7
},
"hiddenSeries": false,
"id": 48,
"interval": "",
"legend": {
@ -4135,6 +4044,7 @@ data:
"x": 12,
"y": 7
},
"hiddenSeries": false,
"id": 6,
"legend": {
"avg": true,
@ -4225,6 +4135,7 @@ data:
"x": 18,
"y": 7
},
"hiddenSeries": false,
"id": 59,
"legend": {
"avg": true,
@ -4316,6 +4227,7 @@ data:
"x": 0,
"y": 12
},
"hiddenSeries": false,
"id": 44,
"legend": {
"avg": true,
@ -4408,6 +4320,7 @@ data:
"x": 6,
"y": 12
},
"hiddenSeries": false,
"id": 49,
"legend": {
"avg": true,
@ -4500,6 +4413,7 @@ data:
"x": 12,
"y": 12
},
"hiddenSeries": false,
"id": 8,
"legend": {
"avg": false,
@ -4590,6 +4504,7 @@ data:
"x": 18,
"y": 12
},
"hiddenSeries": false,
"id": 10,
"legend": {
"avg": true,
@ -4681,6 +4596,7 @@ data:
"x": 0,
"y": 17
},
"hiddenSeries": false,
"id": 62,
"legend": {
"avg": true,
@ -4773,6 +4689,7 @@ data:
"x": 6,
"y": 17
},
"hiddenSeries": false,
"id": 77,
"legend": {
"avg": false,
@ -4800,12 +4717,18 @@ data:
"steppedLine": false,
"targets": [
{
"expr": "sum(che_workspace_status)",
"expr": "che_workspace_total",
"format": "time_series",
"instant": false,
"interval": "",
"intervalFactor": 1,
"legendFormat": "Number of Workspaces",
"legendFormat": "total",
"refId": "A"
},
{
"expr": "sum(che_workspace_status)",
"legendFormat": "status sum",
"refId": "B"
}
],
"thresholds": [],
@ -4851,6 +4774,98 @@ data:
"alignLevel": null
}
},
{
"aliasColors": {},
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": "${datasource}",
"fill": 1,
"fillGradient": 0,
"gridPos": {
"h": 5,
"w": 6,
"x": 12,
"y": 17
},
"hiddenSeries": false,
"id": 110,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"nullPointMode": "null",
"options": {
"dataLinks": []
},
"percentage": false,
"pointradius": 2,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"spaceLength": 10,
"stack": false,
"steppedLine": false,
"targets": [
{
"expr": "sum(che_workspace_starting_attempts_total)",
"legendFormat": "Workspace start attempts",
"refId": "A"
},
{
"expr": "che_workspace_starting_attempts_total{debug='true'}",
"legendFormat": "Workspace start attempts in start-debug mode",
"refId": "B"
}
],
"thresholds": [],
"timeFrom": null,
"timeRegions": [],
"timeShift": null,
"title": "Workspace start attempts",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"buckets": null,
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": 0,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": 0,
"show": true
}
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"collapsed": false,
"datasource": "$datasource",
@ -4881,6 +4896,7 @@ data:
"x": 0,
"y": 23
},
"hiddenSeries": false,
"id": 78,
"legend": {
"avg": false,
@ -4985,6 +5001,7 @@ data:
"x": 0,
"y": 29
},
"hiddenSeries": false,
"id": 16,
"legend": {
"avg": false,
@ -5091,6 +5108,7 @@ data:
"x": 0,
"y": 37
},
"hiddenSeries": false,
"id": 105,
"interval": "",
"legend": {
@ -5179,6 +5197,7 @@ data:
"x": 12,
"y": 37
},
"hiddenSeries": false,
"id": 108,
"interval": "",
"legend": {
@ -9513,11 +9532,11 @@ data:
}
},
{
"datasource": "${datasource}",
"aliasColors": {},
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": "${datasource}",
"fill": 1,
"fillGradient": 0,
"gridPos": {
@ -9578,22 +9597,22 @@ data:
},
"yaxes": [
{
"decimals": 0,
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": 0,
"show": true,
"decimals": 0
"show": true
},
{
"decimals": 0,
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": 0,
"show": true,
"decimals": 0
"show": true
}
],
"yaxis": {
@ -9673,12 +9692,16 @@ data:
}
],
"refresh": "15m",
"schemaVersion": 19,
"schemaVersion": 22,
"style": "dark",
"tags": [],
"templating": {
"list": [
{
"current": {
"text": "che",
"value": "che"
},
"hide": 0,
"includeAll": false,
"label": null,
@ -9726,4 +9749,4 @@ data:
"title": "Che Server",
"uid": "sL0Klq_mz",
"version": 1
}
}

View File

@ -235,6 +235,19 @@ public class MultiuserJpaWorkspaceDao implements WorkspaceDao {
}
}
@Override
@Transactional
public long getWorkspacesTotalCount() throws ServerException {
try {
return managerProvider
.get()
.createNamedQuery("Workspace.getWorkspacesTotalCount", Long.class)
.getSingleResult();
} catch (RuntimeException x) {
throw new ServerException(x.getLocalizedMessage(), x);
}
}
@Transactional
protected void doCreate(WorkspaceImpl workspace) {
if (workspace.getConfig() != null) {

View File

@ -20,6 +20,7 @@ import java.util.Arrays;
import java.util.List;
import javax.persistence.EntityManager;
import org.eclipse.che.account.spi.AccountImpl;
import org.eclipse.che.api.core.ServerException;
import org.eclipse.che.api.user.server.model.impl.UserImpl;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceConfigImpl;
import org.eclipse.che.api.workspace.server.model.impl.WorkspaceImpl;
@ -126,6 +127,11 @@ public class MultiuserJpaWorkspaceDaoTest {
manager.getTransaction().commit();
}
@Test
public void shouldGetTotalWorkspaceCount() throws ServerException {
assertEquals(dao.getWorkspacesTotalCount(), 3);
}
@AfterClass
public void shutdown() throws Exception {
tckResourcesCleaner.clean();

View File

@ -51,6 +51,10 @@
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-user</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-workspace</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-workspace-activity</artifactId>

View File

@ -0,0 +1,48 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.api.metrics;
import static org.eclipse.che.api.metrics.WorkspaceBinders.workspaceMetric;
import io.micrometer.core.instrument.Gauge;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.binder.MeterBinder;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.eclipse.che.api.core.ServerException;
import org.eclipse.che.api.workspace.server.WorkspaceManager;
/** Provides metrics of workspace. */
@Singleton
public class WorkspaceMeterBinder implements MeterBinder {
private final WorkspaceManager workspaceManager;
@Inject
public WorkspaceMeterBinder(WorkspaceManager workspaceManager) {
this.workspaceManager = workspaceManager;
}
@Override
public void bindTo(MeterRegistry registry) {
Gauge.builder(workspaceMetric("total"), this::count)
.description("Total number of workspaces")
.register(registry);
}
private double count() {
try {
return workspaceManager.getWorkspacesTotalCount();
} catch (ServerException e) {
return Double.NaN;
}
}
}

View File

@ -35,5 +35,6 @@ public class WsMasterMetricsModule extends AbstractModule {
meterMultibinder.addBinding().to(WorkspaceStartAttemptsMeterBinder.class);
meterMultibinder.addBinding().to(UserMeterBinder.class);
meterMultibinder.addBinding().to(RuntimeLogMeterBinder.class);
meterMultibinder.addBinding().to(WorkspaceMeterBinder.class);
}
}

View File

@ -585,6 +585,16 @@ public class WorkspaceManager {
}
}
/**
* Gets total count of all workspaces
*
* @return workspaces count
* @throws ServerException when any error occurs
*/
public long getWorkspacesTotalCount() throws ServerException {
return workspaceDao.getWorkspacesTotalCount();
}
private WorkspaceImpl doCreateWorkspace(
WorkspaceConfig config, Account account, Map<String, String> attributes, boolean isTemporary)
throws ConflictException, ServerException {

View File

@ -262,6 +262,19 @@ public class JpaWorkspaceDao implements WorkspaceDao {
return merged;
}
@Override
@Transactional
public long getWorkspacesTotalCount() throws ServerException {
try {
return managerProvider
.get()
.createNamedQuery("Workspace.getWorkspacesTotalCount", Long.class)
.getSingleResult();
} catch (RuntimeException x) {
throw new ServerException(x.getLocalizedMessage(), x);
}
}
@Singleton
public static class RemoveWorkspaceBeforeAccountRemovedEventSubscriber
extends CascadeEventSubscriber<BeforeAccountRemovedEvent> {

View File

@ -67,6 +67,9 @@ import org.eclipse.persistence.descriptors.DescriptorEventAdapter;
@NamedQuery(
name = "Workspace.getByNamespaceCount",
query = "SELECT COUNT(w) " + "FROM Workspace w " + "WHERE w.account.name = :namespace "),
@NamedQuery(
name = "Workspace.getWorkspacesTotalCount",
query = "SELECT COUNT(w) FROM Workspace w"),
@NamedQuery(
name = "Workspace.getByTemporaryCount",
query = "SELECT COUNT(w) " + "FROM Workspace w " + "WHERE w.isTemporary = :temporary ")

View File

@ -134,4 +134,12 @@ public interface WorkspaceDao {
*/
Page<WorkspaceImpl> getWorkspaces(boolean isTemporary, int maxItems, long skipCount)
throws ServerException;
/**
* Get the count of all workspaces from the persistent layer.
*
* @return workspace count
* @throws ServerException when any error occurs
*/
long getWorkspacesTotalCount() throws ServerException;
}

View File

@ -127,6 +127,31 @@ public class WorkspaceDaoTest {
workspaceRepo.createAll(Stream.of(workspaces).map(WorkspaceImpl::new).collect(toList()));
}
@Test
public void shouldBeAbleToCountWorkspaces() throws ServerException {
assertEquals(workspaceDao.getWorkspacesTotalCount(), COUNT_OF_WORKSPACES);
}
@Test
public void shouldBeAbleToCountNewWorkspaces() throws ServerException, TckRepositoryException {
// given
// when
workspaceRepo.createAll(
ImmutableList.of(createWorkspaceFromDevfile("id222", accounts[0], "name-bbb")));
// then
assertEquals(workspaceDao.getWorkspacesTotalCount(), COUNT_OF_WORKSPACES + 1);
}
@Test
public void shouldBeAbleToSubtractRemovedWorkspaces()
throws ServerException, TckRepositoryException {
// given
// when
workspaceDao.remove(workspaces[1].getId());
// then
assertEquals(workspaceDao.getWorkspacesTotalCount(), COUNT_OF_WORKSPACES - 1);
}
@Test
public void shouldGetWorkspaceById() throws Exception {
final WorkspaceImpl workspace = workspaces[0];