From 7941ea01731364ce635c6f6078896503c83fbeab Mon Sep 17 00:00:00 2001 From: lukasz-jarocki-sonarsource Date: Tue, 9 Jul 2024 14:00:39 +0200 Subject: [PATCH] SONAR-22479 added new interface for adding new telemetry metrics --- .../org/sonar/server/telemetry/Dimension.java | 29 +++++++ .../sonar/server/telemetry/Granularity.java | 29 +++++++ .../telemetry/TelemetryDataProvider.java | 78 +++++++++++++++++++ .../server/telemetry/TelemetryDataType.java | 28 +++++++ .../platformlevel/PlatformLevel4.java | 4 + .../telemetry/TelemetryVersionProvider.java | 60 ++++++++++++++ .../platform/telemetry/package-info.java | 23 ++++++ .../TelemetryVersionProviderTest.java | 50 ++++++++++++ 8 files changed, 301 insertions(+) create mode 100644 server/sonar-server-common/src/main/java/org/sonar/server/telemetry/Dimension.java create mode 100644 server/sonar-server-common/src/main/java/org/sonar/server/telemetry/Granularity.java create mode 100644 server/sonar-server-common/src/main/java/org/sonar/server/telemetry/TelemetryDataProvider.java create mode 100644 server/sonar-server-common/src/main/java/org/sonar/server/telemetry/TelemetryDataType.java create mode 100644 server/sonar-webserver/src/main/java/org/sonar/server/platform/telemetry/TelemetryVersionProvider.java create mode 100644 server/sonar-webserver/src/main/java/org/sonar/server/platform/telemetry/package-info.java create mode 100644 server/sonar-webserver/src/test/java/org/sonar/server/telemetry/TelemetryVersionProviderTest.java diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/telemetry/Dimension.java b/server/sonar-server-common/src/main/java/org/sonar/server/telemetry/Dimension.java new file mode 100644 index 00000000000..db9654398bd --- /dev/null +++ b/server/sonar-server-common/src/main/java/org/sonar/server/telemetry/Dimension.java @@ -0,0 +1,29 @@ +/* + * SonarQube + * Copyright (C) 2009-2024 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.telemetry; + +/** + * Represents the dimension of the data provided by a {@link TelemetryDataProvider}. + * {@link Dimension#PROJECT}, {@link Dimension#LANGUAGE} and {@link Dimension#USER} should not provide aggregated data. + * For aggregated data (i.e. average number of lines of code per project), use #INSTALLATION. + */ +public enum Dimension { + INSTALLATION, PROJECT, USER, LANGUAGE +} diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/telemetry/Granularity.java b/server/sonar-server-common/src/main/java/org/sonar/server/telemetry/Granularity.java new file mode 100644 index 00000000000..b44d6391c6b --- /dev/null +++ b/server/sonar-server-common/src/main/java/org/sonar/server/telemetry/Granularity.java @@ -0,0 +1,29 @@ +/* + * SonarQube + * Copyright (C) 2009-2024 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.telemetry; + +/** + * Represent the granularity of the data provided by a {@link TelemetryDataProvider}. This both defines the time period between to pushes to + * telemetry server for a given metric and the time period that the data represents. + * Modifying this enum needs to be discussed beforehand with Data Platform team. + */ +public enum Granularity { + DAILY, WEEKLY, MONTHLY; +} diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/telemetry/TelemetryDataProvider.java b/server/sonar-server-common/src/main/java/org/sonar/server/telemetry/TelemetryDataProvider.java new file mode 100644 index 00000000000..8dc200306af --- /dev/null +++ b/server/sonar-server-common/src/main/java/org/sonar/server/telemetry/TelemetryDataProvider.java @@ -0,0 +1,78 @@ +/* + * SonarQube + * Copyright (C) 2009-2024 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.telemetry; + +import java.util.Map; + +/** + * This interface is used to provide data to the telemetry system. The telemetry system will call the methods of this interface to get the + * data that will be sent to the telemetry server. + * If you want to add new metric to the telemetry system, you need to create a new implementation of this interface and register it in the + * Spring context as a bean. + * + * @param type of the value provided by this instance. Should be either {@link java.lang.Boolean}, {@link java.lang.String}, + * {@link java.lang.Integer} or {@link java.lang.Float}. + */ +public interface TelemetryDataProvider { + + /** + * @return the key of the metric that will be used to store the value of the data provided by this instance. The combination of + * metric key and dimension needs to be universally unique. The metric key needs to be written in snake_case. + */ + String getMetricKey(); + + /** + * @return the dimension ("category") of the data provided by this instance. The combination of metric key and dimension needs to be + * universally unique. + */ + Dimension getDimension(); + + /** + * @return returns the granularity of this telemetry metric. + * @see Granularity + */ + Granularity getGranularity(); + + /** + * @return the type of the data provided by this instance. + */ + TelemetryDataType getType(); + + /** + * The implementation of this method might often need to make a call to a database. + * For each metric either this method or {@link TelemetryDataProvider#getUuidValues()} should be implemented and used. Not both at once. + * + * @return the value of the data provided by this instance. + */ + default T getValue() { + throw new IllegalStateException("Not implemented"); + } + + /** + * The implementation of this method might often need to make a call to a database. + * Similiar as {@link TelemetryDataProvider#getValue()} this method returns values of the metric. Some of the metrics + * associate a UUID with a value. This method is used to return all the values associated with the UUIDs. + * + * @return map of UUIDs and their values. + */ + default Map getUuidValues() { + throw new IllegalStateException("Not implemented"); + } +} diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/telemetry/TelemetryDataType.java b/server/sonar-server-common/src/main/java/org/sonar/server/telemetry/TelemetryDataType.java new file mode 100644 index 00000000000..923e9894416 --- /dev/null +++ b/server/sonar-server-common/src/main/java/org/sonar/server/telemetry/TelemetryDataType.java @@ -0,0 +1,28 @@ +/* + * SonarQube + * Copyright (C) 2009-2024 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.telemetry; + +/** + * Represents the type of the data provided by a {@link TelemetryDataProvider}. + * Modifying this enum needs to be discussed beforehand with Data Platform team. + */ +public enum TelemetryDataType { + BOOLEAN, STRING, INTEGER, FLOAT +} diff --git a/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java b/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java index 39074ba7dba..44b54cd1ad1 100644 --- a/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java +++ b/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java @@ -184,6 +184,7 @@ import org.sonar.server.platform.PersistentSettings; import org.sonar.server.platform.SystemInfoWriterModule; import org.sonar.server.platform.WebCoreExtensionsInstaller; import org.sonar.server.platform.db.CheckAnyonePermissionsAtStartup; +import org.sonar.server.platform.telemetry.TelemetryVersionProvider; import org.sonar.server.platform.web.ActionDeprecationLoggerInterceptor; import org.sonar.server.platform.web.SonarLintConnectionFilter; import org.sonar.server.platform.web.WebServiceFilter; @@ -664,6 +665,9 @@ public class PlatformLevel4 extends PlatformLevel { CloudUsageDataProvider.class, QualityProfileDataProvider.class, + //new telemetry metrics + TelemetryVersionProvider.class, + // monitoring ServerMonitoringMetrics.class, diff --git a/server/sonar-webserver/src/main/java/org/sonar/server/platform/telemetry/TelemetryVersionProvider.java b/server/sonar-webserver/src/main/java/org/sonar/server/platform/telemetry/TelemetryVersionProvider.java new file mode 100644 index 00000000000..12b0f40c17a --- /dev/null +++ b/server/sonar-webserver/src/main/java/org/sonar/server/platform/telemetry/TelemetryVersionProvider.java @@ -0,0 +1,60 @@ +/* + * SonarQube + * Copyright (C) 2009-2024 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.platform.telemetry; + +import org.sonar.api.platform.Server; +import org.sonar.server.telemetry.Dimension; +import org.sonar.server.telemetry.Granularity; +import org.sonar.server.telemetry.TelemetryDataProvider; +import org.sonar.server.telemetry.TelemetryDataType; + +public class TelemetryVersionProvider implements TelemetryDataProvider { + + private final Server server; + + public TelemetryVersionProvider(Server server) { + this.server = server; + } + + @Override + public String getMetricKey() { + return "version"; + } + + @Override + public Dimension getDimension() { + return Dimension.INSTALLATION; + } + + @Override + public Granularity getGranularity() { + return Granularity.DAILY; + } + + @Override + public TelemetryDataType getType() { + return TelemetryDataType.STRING; + } + + @Override + public String getValue() { + return server.getVersion(); + } +} diff --git a/server/sonar-webserver/src/main/java/org/sonar/server/platform/telemetry/package-info.java b/server/sonar-webserver/src/main/java/org/sonar/server/platform/telemetry/package-info.java new file mode 100644 index 00000000000..007408add84 --- /dev/null +++ b/server/sonar-webserver/src/main/java/org/sonar/server/platform/telemetry/package-info.java @@ -0,0 +1,23 @@ +/* + * SonarQube + * Copyright (C) 2009-2024 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +@ParametersAreNonnullByDefault +package org.sonar.server.platform.telemetry; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/server/sonar-webserver/src/test/java/org/sonar/server/telemetry/TelemetryVersionProviderTest.java b/server/sonar-webserver/src/test/java/org/sonar/server/telemetry/TelemetryVersionProviderTest.java new file mode 100644 index 00000000000..4335f71f9a6 --- /dev/null +++ b/server/sonar-webserver/src/test/java/org/sonar/server/telemetry/TelemetryVersionProviderTest.java @@ -0,0 +1,50 @@ +/* + * SonarQube + * Copyright (C) 2009-2024 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.telemetry; + +import org.junit.jupiter.api.Test; +import org.sonar.api.platform.Server; +import org.sonar.server.platform.telemetry.TelemetryVersionProvider; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +class TelemetryVersionProviderTest { + + /** + * To increase coverage :shrug: + */ + @Test + void testGetters() { + Server server = mock(); + when(server.getVersion()).thenReturn("10.6"); + + TelemetryVersionProvider telemetryVersionProvider = new TelemetryVersionProvider(server); + + assertEquals("version", telemetryVersionProvider.getMetricKey()); + assertEquals(Dimension.INSTALLATION, telemetryVersionProvider.getDimension()); + assertEquals(Granularity.DAILY, telemetryVersionProvider.getGranularity()); + assertEquals(TelemetryDataType.STRING, telemetryVersionProvider.getType()); + assertEquals("10.6", telemetryVersionProvider.getValue()); + assertThrows(IllegalStateException.class, telemetryVersionProvider::getUuidValues); + } +} -- 2.39.5