Successfully started workspaces ratio (#12852)

Successfully started workspaces ratio

Signed-off-by: Sergii Kabashniuk <skabashniuk@redhat.com>
7.20.x
Sergii Kabashniuk 2019-03-12 13:25:11 +02:00 committed by GitHub
parent b4702cd885
commit 7a1d3964a6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 447 additions and 11 deletions

View File

@ -3964,6 +3964,7 @@ objects:
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"paceLength": 10,
"percentage": false,
"pointradius": 5,
"points": false,
@ -4049,6 +4050,7 @@ objects:
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"paceLength": 10,
"percentage": false,
"pointradius": 5,
"points": false,
@ -4134,6 +4136,7 @@ objects:
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"paceLength": 10,
"percentage": false,
"pointradius": 5,
"points": false,
@ -4193,13 +4196,107 @@ objects:
"alignLevel": null
}
},
{
"aliasColors": {},
"bars": false,
"dashLength": 10,
"dashes": false,
"datasource": "Che",
"description": "",
"fill": 1,
"gridPos": {
"h": 5,
"w": 11,
"x": 0,
"y": 6
},
"id": 36,
"interval": "",
"legend": {
"avg": true,
"current": true,
"max": true,
"min": true,
"show": true,
"total": false,
"values": true
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "null as zero",
"paceLength": 10,
"percentage": false,
"pointradius": 2,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"stack": true,
"steppedLine": false,
"targets": [
{
"expr": "sum(increase(che_workspace_failure_total{while=\"STARTING\"} [1h])) /(sum(increase(che_workspace_failure_total{while=\"STARTING\"} [1h])) + sum(increase(che_workspace_started_total [1h])))",
"format": "time_series",
"intervalFactor": 1,
"legendFormat": "fail",
"refId": "A"
},
{
"expr": "sum(increase(che_workspace_started_total [1h]))/(sum(increase(che_workspace_failure_total{while=\"STARTING\"} [1h])) + sum(increase(che_workspace_started_total [1h])))",
"format": "time_series",
"intervalFactor": 1,
"legendFormat": "success",
"refId": "B"
}
],
"thresholds": [],
"timeFrom": null,
"timeRegions": [],
"timeShift": null,
"title": "Workspace start rate",
"tooltip": {
"shared": true,
"sort": 0,
"value_type": "individual"
},
"type": "graph",
"xaxis": {
"buckets": null,
"mode": "time",
"name": null,
"show": true,
"values": []
},
"yaxes": [
{
"format": "percentunit",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": false
}
],
"yaxis": {
"align": false,
"alignLevel": null
}
},
{
"collapsed": false,
"gridPos": {
"h": 1,
"w": 24,
"x": 0,
"y": 6
"y": 11
},
"id": 24,
"panels": [],
@ -4217,7 +4314,7 @@ objects:
"h": 7,
"w": 11,
"x": 0,
"y": 7
"y": 12
},
"id": 16,
"legend": {
@ -4233,6 +4330,7 @@ objects:
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"paceLength": 10,
"percentage": false,
"pointradius": 5,
"points": false,
@ -4298,7 +4396,7 @@ objects:
"h": 1,
"w": 24,
"x": 0,
"y": 14
"y": 19
},
"id": 22,
"panels": [],
@ -4316,7 +4414,7 @@ objects:
"h": 7,
"w": 9,
"x": 0,
"y": 15
"y": 20
},
"id": 18,
"legend": {
@ -4333,6 +4431,7 @@ objects:
"linewidth": 1,
"links": [],
"nullPointMode": "null as zero",
"paceLength": 10,
"percentage": false,
"pointradius": 5,
"points": false,
@ -4427,7 +4526,7 @@ objects:
"h": 7,
"w": 7,
"x": 9,
"y": 15
"y": 20
},
"id": 26,
"legend": {
@ -4444,6 +4543,7 @@ objects:
"linewidth": 1,
"links": [],
"nullPointMode": "null as zero",
"paceLength": 10,
"percentage": false,
"pointradius": 5,
"points": false,
@ -4523,7 +4623,7 @@ objects:
"h": 7,
"w": 7,
"x": 16,
"y": 15
"y": 20
},
"id": 32,
"legend": {
@ -4542,6 +4642,7 @@ objects:
"linewidth": 1,
"links": [],
"nullPointMode": "null",
"paceLength": 10,
"percentage": false,
"pointradius": 5,
"points": false,
@ -4621,7 +4722,7 @@ objects:
"h": 8,
"w": 9,
"x": 0,
"y": 22
"y": 27
},
"id": 30,
"legend": {
@ -4637,6 +4738,7 @@ objects:
"linewidth": 1,
"links": [],
"nullPointMode": "null as zero",
"paceLength": 10,
"percentage": false,
"pointradius": 5,
"points": false,
@ -4713,7 +4815,7 @@ objects:
"h": 8,
"w": 7,
"x": 9,
"y": 22
"y": 27
},
"id": 34,
"legend": {
@ -4729,6 +4831,7 @@ objects:
"linewidth": 1,
"links": [],
"nullPointMode": "null as zero",
"paceLength": 10,
"percentage": false,
"pointradius": 5,
"points": false,
@ -4807,7 +4910,7 @@ objects:
"h": 8,
"w": 7,
"x": 16,
"y": 22
"y": 27
},
"id": 28,
"legend": {
@ -4823,6 +4926,7 @@ objects:
"linewidth": 1,
"links": [],
"nullPointMode": "null as zero",
"paceLength": 10,
"percentage": false,
"pointradius": 5,
"points": false,
@ -4892,14 +4996,14 @@ objects:
}
],
"refresh": "5s",
"schemaVersion": 16,
"schemaVersion": 18,
"style": "dark",
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-5m",
"from": "now-1h",
"to": "now"
},
"timepicker": {

View File

@ -51,6 +51,11 @@
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-workspace-shared</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.che.core</groupId>
<artifactId>che-core-api-dto</artifactId>

View File

@ -0,0 +1,54 @@
/*
* 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 com.google.inject.Inject;
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.binder.MeterBinder;
import javax.inject.Singleton;
import org.eclipse.che.api.core.model.workspace.WorkspaceStatus;
import org.eclipse.che.api.core.notification.EventService;
import org.eclipse.che.api.workspace.shared.dto.event.WorkspaceStatusEvent;
/** Counts number of attempts to start workspace. */
@Singleton
public class WorkspaceStartAttemptsMeterBinder implements MeterBinder {
private final EventService eventService;
private Counter startingCounter;
@Inject
public WorkspaceStartAttemptsMeterBinder(EventService eventService) {
this.eventService = eventService;
}
@Override
public void bindTo(MeterRegistry registry) {
startingCounter =
Counter.builder(workspaceMetric("starting_attempts.total"))
.description("The count of workspaces start attempts")
.register(registry);
// only subscribe to the event once we have the counters ready
eventService.subscribe(
event -> {
if (event.getPrevStatus() == WorkspaceStatus.STOPPED
&& event.getStatus() == WorkspaceStatus.STARTING) {
startingCounter.increment();
}
},
WorkspaceStatusEvent.class);
}
}

View File

@ -0,0 +1,54 @@
/*
* 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 com.google.inject.Inject;
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.binder.MeterBinder;
import javax.inject.Singleton;
import org.eclipse.che.api.core.model.workspace.WorkspaceStatus;
import org.eclipse.che.api.core.notification.EventService;
import org.eclipse.che.api.workspace.shared.dto.event.WorkspaceStatusEvent;
/** Counts number of successfully started workspaces. */
@Singleton
public class WorkspaceSuccessfulStartAttemptsMeterBinder implements MeterBinder {
private final EventService eventService;
private Counter startedCounter;
@Inject
public WorkspaceSuccessfulStartAttemptsMeterBinder(EventService eventService) {
this.eventService = eventService;
}
@Override
public void bindTo(MeterRegistry registry) {
startedCounter =
Counter.builder(workspaceMetric("started.total"))
.description("The count of started workspaces")
.register(registry);
// only subscribe to the event once we have the counters ready
eventService.subscribe(
event -> {
if (event.getPrevStatus() == WorkspaceStatus.STARTING
&& event.getStatus() == WorkspaceStatus.RUNNING) {
startedCounter.increment();
}
},
WorkspaceStatusEvent.class);
}
}

View File

@ -28,5 +28,7 @@ public class WsMasterMetricsModule extends AbstractModule {
meterMultibinder.addBinding().to(WorkspaceActivityMeterBinder.class);
meterMultibinder.addBinding().to(WorkspaceFailureMeterBinder.class);
meterMultibinder.addBinding().to(WorkspaceSuccessfulStartAttemptsMeterBinder.class);
meterMultibinder.addBinding().to(WorkspaceStartAttemptsMeterBinder.class);
}
}

View File

@ -0,0 +1,95 @@
/*
* 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 java.util.Arrays.asList;
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.che.api.core.model.workspace.WorkspaceStatus;
import org.eclipse.che.api.core.notification.EventService;
import org.eclipse.che.api.workspace.shared.dto.event.WorkspaceStatusEvent;
import org.eclipse.che.dto.server.DtoFactory;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class WorkspaceStartAttemptsMeterBinderTest {
private EventService eventService;
private MeterRegistry registry;
@BeforeMethod
public void setUp() {
eventService = new EventService();
registry = new SimpleMeterRegistry();
}
@Test(dataProvider = "allStatusTransitionsWithoutStarting")
public void shouldNotCollectEvents(WorkspaceStatus from, WorkspaceStatus to) {
// given
WorkspaceStartAttemptsMeterBinder meterBinder =
new WorkspaceStartAttemptsMeterBinder(eventService);
meterBinder.bindTo(registry);
// when
eventService.publish(
DtoFactory.newDto(WorkspaceStatusEvent.class)
.withPrevStatus(from)
.withStatus(to)
.withWorkspaceId("id1"));
// then
Counter successful = registry.find("che.workspace.starting_attempts.total").counter();
Assert.assertEquals(successful.count(), 0.0);
}
@Test
public void shouldCollectOnlyStart() {
// given
WorkspaceStartAttemptsMeterBinder meterBinder =
new WorkspaceStartAttemptsMeterBinder(eventService);
meterBinder.bindTo(registry);
// when
eventService.publish(
DtoFactory.newDto(WorkspaceStatusEvent.class)
.withPrevStatus(WorkspaceStatus.STOPPED)
.withStatus(WorkspaceStatus.STARTING)
.withWorkspaceId("id1"));
// then
Counter successful = registry.find("che.workspace.starting_attempts.total").counter();
Assert.assertEquals(successful.count(), 1.0);
}
@DataProvider
public Object[][] allStatusTransitionsWithoutStarting() {
List<List<WorkspaceStatus>> transitions = new ArrayList<>(9);
for (WorkspaceStatus from : WorkspaceStatus.values()) {
for (WorkspaceStatus to : WorkspaceStatus.values()) {
if (from == WorkspaceStatus.STOPPED && to == WorkspaceStatus.STARTING) {
continue;
}
transitions.add(asList(from, to));
}
}
return transitions.stream().map(List::toArray).toArray(Object[][]::new);
}
}

View File

@ -0,0 +1,95 @@
/*
* 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 java.util.Arrays.asList;
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.che.api.core.model.workspace.WorkspaceStatus;
import org.eclipse.che.api.core.notification.EventService;
import org.eclipse.che.api.workspace.shared.dto.event.WorkspaceStatusEvent;
import org.eclipse.che.dto.server.DtoFactory;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class WorkspaceSuccessfulStartAttemptsMeterBinderTest {
private EventService eventService;
private MeterRegistry registry;
@BeforeMethod
public void setUp() {
eventService = new EventService();
registry = new SimpleMeterRegistry();
}
@Test(dataProvider = "allStatusTransitionsWithoutRunning")
public void shouldNotCollectEvents(WorkspaceStatus from, WorkspaceStatus to) {
// given
WorkspaceSuccessfulStartAttemptsMeterBinder meterBinder =
new WorkspaceSuccessfulStartAttemptsMeterBinder(eventService);
meterBinder.bindTo(registry);
// when
eventService.publish(
DtoFactory.newDto(WorkspaceStatusEvent.class)
.withPrevStatus(from)
.withStatus(to)
.withWorkspaceId("id1"));
// then
Counter successful = registry.find("che.workspace.started.total").counter();
Assert.assertEquals(successful.count(), 0.0);
}
@Test
public void shouldCollectOnlyStarted() {
// given
WorkspaceSuccessfulStartAttemptsMeterBinder meterBinder =
new WorkspaceSuccessfulStartAttemptsMeterBinder(eventService);
meterBinder.bindTo(registry);
// when
eventService.publish(
DtoFactory.newDto(WorkspaceStatusEvent.class)
.withPrevStatus(WorkspaceStatus.STARTING)
.withStatus(WorkspaceStatus.RUNNING)
.withWorkspaceId("id1"));
// then
Counter successful = registry.find("che.workspace.started.total").counter();
Assert.assertEquals(successful.count(), 1.0);
}
@DataProvider
public Object[][] allStatusTransitionsWithoutRunning() {
List<List<WorkspaceStatus>> transitions = new ArrayList<>(9);
for (WorkspaceStatus from : WorkspaceStatus.values()) {
for (WorkspaceStatus to : WorkspaceStatus.values()) {
if (from == WorkspaceStatus.STARTING && to == WorkspaceStatus.RUNNING) {
continue;
}
transitions.add(asList(from, to));
}
}
return transitions.stream().map(List::toArray).toArray(Object[][]::new);
}
}

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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
-->
<configuration>
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%-41(%date[%.15thread]) %-45([%-5level] [%.30logger{30} %L]) - %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="stdout"/>
</root>
</configuration>