This is an automated email from the ASF dual-hosted git repository. solomax pushed a commit to branch jakarta-spring-6 in repository https://gitbox.apache.org/repos/asf/openmeetings.git
commit 9a6c2d5162355ed5ce15dda2bdd44c654a69b7c2 Author: Maxim Solodovnik <solo...@apache.org> AuthorDate: Sun Oct 8 20:08:13 2023 +0700 [OPENMEETINGS-2756] modules are restructured to remove 'test-jar'; Prometheus is updated to 1.0.0 --- openmeetings-core/pom.xml | 21 +- openmeetings-core/src/test/java/module-info.test | 66 ----- openmeetings-db/pom.xml | 8 - openmeetings-db/src/test/java/module-info.test | 87 ------ openmeetings-install/pom.xml | 7 - .../src/test/java/module-info.test | 57 ---- openmeetings-mediaserver/pom.xml | 12 +- .../src/test/java/module-info.test | 51 ---- openmeetings-screenshare/pom.xml | 1 - openmeetings-server/pom.xml | 1 + .../pom.xml | 34 +-- .../src/main/java/module-info.java | 14 +- .../apache/openmeetings/test/NonJenkinsTest.java | 0 openmeetings-util/pom.xml | 18 +- openmeetings-util/src/main/java/module-info.java | 4 +- .../util/logging/PrometheusAspect.java | 14 +- .../openmeetings/util/logging/PrometheusUtil.java | 37 --- .../util/logging/TimedApplication.java | 1 - .../openmeetings/util/logging/TimedDatabase.java | 1 - openmeetings-util/src/test/java/module-info.test | 56 ---- openmeetings-web/pom.xml | 16 +- openmeetings-web/src/main/java/module-info.java | 5 +- .../util/logging/OpenMeetingsMetricsServlet.java | 19 +- .../web/util/logging/TomcatGenericExports.java | 324 --------------------- .../openmeetings/web/util/logging/TomcatStats.java | 314 ++++++++++++++++++++ .../webapp/WEB-INF/classes/applicationContext.xml | 2 +- openmeetings-web/src/main/webapp/WEB-INF/web.xml | 50 +--- openmeetings-web/src/test/java/module-info.test | 92 ------ openmeetings-webservice/pom.xml | 12 +- .../src/test/java/module-info.test | 58 ---- pom.xml | 82 ++++-- 31 files changed, 435 insertions(+), 1029 deletions(-) diff --git a/openmeetings-core/pom.xml b/openmeetings-core/pom.xml index 54a96621f..2339024c3 100644 --- a/openmeetings-core/pom.xml +++ b/openmeetings-core/pom.xml @@ -34,7 +34,7 @@ </properties> <build> <plugins> - <!--plugin> + <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-javadoc-plugin</artifactId> <executions> @@ -51,18 +51,6 @@ <goals> <goal>javadoc-no-fork</goal> </goals> - <phase>generate-resources</phase> - </execution> - </executions> - </plugin--> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-jar-plugin</artifactId> - <executions> - <execution> - <goals> - <goal>test-jar</goal> - </goals> </execution> </executions> </plugin> @@ -118,12 +106,5 @@ <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-params</artifactId> </dependency> - <dependency> - <groupId>org.apache.openmeetings</groupId> - <artifactId>openmeetings-util</artifactId> - <version>${project.version}</version> - <type>test-jar</type> - <scope>test</scope> - </dependency> </dependencies> </project> diff --git a/openmeetings-core/src/test/java/module-info.test b/openmeetings-core/src/test/java/module-info.test deleted file mode 100644 index fb0ceeb30..000000000 --- a/openmeetings-core/src/test/java/module-info.test +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License") + you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -open module org.apache.openmeetings.core { - // This one should be in-sync with module-info.java - exports org.apache.openmeetings.core.converter; - exports org.apache.openmeetings.core.data.file; - exports org.apache.openmeetings.core.ldap; - exports org.apache.openmeetings.core.mail; - exports org.apache.openmeetings.core.notifier; - exports org.apache.openmeetings.core.rss; - exports org.apache.openmeetings.core.sip; - exports org.apache.openmeetings.core.util; - - requires com.github.openjson; - - requires jakarta.annotation; - requires jakarta.inject; - requires jakarta.mail; - - requires org.apache.commons.io; - requires org.apache.commons.lang3; - - requires org.apache.tika.core; - requires org.apache.tika.parser.image; - - requires org.apache.openmeetings.db; - requires org.apache.openmeetings.util; - - requires org.apache.wicket.core; - requires org.apache.wicket.websocket.core; - requires org.apache.wicket.util; - - requires java.xml; - - requires xstream; - - requires jodconverter.core; - requires jodconverter.local; - requires org.apache.directory.ldap.api.all; - requires asterisk.java; - requires jain.sip.ri; - - requires spring.context; - - requires org.slf4j; - - //tests - requires org.junit.jupiter.api; -} diff --git a/openmeetings-db/pom.xml b/openmeetings-db/pom.xml index 3ba12399c..ed2df7a38 100644 --- a/openmeetings-db/pom.xml +++ b/openmeetings-db/pom.xml @@ -112,13 +112,6 @@ <groupId>com.google.code.findbugs</groupId> <artifactId>jsr305</artifactId> </dependency> - <dependency> - <groupId>org.apache.openmeetings</groupId> - <artifactId>openmeetings-util</artifactId> - <version>${project.version}</version> - <type>test-jar</type> - <scope>test</scope> - </dependency> </dependencies> <build> <plugins> @@ -139,7 +132,6 @@ <goals> <goal>javadoc-no-fork</goal> </goals> - <phase>generate-resources</phase> </execution> </executions> </plugin--> diff --git a/openmeetings-db/src/test/java/module-info.test b/openmeetings-db/src/test/java/module-info.test deleted file mode 100644 index fd9ed1196..000000000 --- a/openmeetings-db/src/test/java/module-info.test +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License") + you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -open module org.apache.openmeetings.db { - // This one should be in-sync with module-info.java - exports org.apache.openmeetings; - exports org.apache.openmeetings.db.bind; - exports org.apache.openmeetings.db.bind.adapter; - exports org.apache.openmeetings.db.dao; - exports org.apache.openmeetings.db.dao.basic; - exports org.apache.openmeetings.db.dao.calendar; - exports org.apache.openmeetings.db.dao.file; - exports org.apache.openmeetings.db.dao.label; - exports org.apache.openmeetings.db.dao.log; - exports org.apache.openmeetings.db.dao.record; - exports org.apache.openmeetings.db.dao.room; - exports org.apache.openmeetings.db.dao.server; - exports org.apache.openmeetings.db.dao.user; - exports org.apache.openmeetings.db.dto.basic; - exports org.apache.openmeetings.db.dto.calendar; - exports org.apache.openmeetings.db.dto.file; - exports org.apache.openmeetings.db.dto.record; - exports org.apache.openmeetings.db.dto.room; - exports org.apache.openmeetings.db.dto.user; - exports org.apache.openmeetings.db.entity; - exports org.apache.openmeetings.db.entity.basic; - exports org.apache.openmeetings.db.entity.calendar; - exports org.apache.openmeetings.db.entity.file; - exports org.apache.openmeetings.db.entity.label; - exports org.apache.openmeetings.db.entity.log; - exports org.apache.openmeetings.db.entity.record; - exports org.apache.openmeetings.db.entity.room; - exports org.apache.openmeetings.db.entity.server; - exports org.apache.openmeetings.db.entity.user; - exports org.apache.openmeetings.db.manager; - exports org.apache.openmeetings.db.mapper; - exports org.apache.openmeetings.db.util; - exports org.apache.openmeetings.db.util.ws; - - requires com.github.openjson; - - requires org.apache.commons.lang3; - requires org.apache.commons.text; - - requires org.apache.openjpa; - - requires org.apache.openmeetings.util; - - requires org.apache.wicket.core; - requires org.apache.wicket.extensions; - requires org.apache.wicket.request; - requires org.apache.wicket.util; - requires org.apache.wicket.websocket.core; - - requires spring.beans; - requires spring.web; - requires spring.core; - requires spring.tx; - requires spring.context; - - requires jakarta.annotation; - requires jakarta.inject; - requires jakarta.persistence; - requires jakarta.servlet; - requires jakarta.xml.bind; - - requires org.dom4j; - requires org.slf4j; - - //tests - requires org.junit.jupiter.api; -} diff --git a/openmeetings-install/pom.xml b/openmeetings-install/pom.xml index 3e37d0ed7..4b563bab0 100644 --- a/openmeetings-install/pom.xml +++ b/openmeetings-install/pom.xml @@ -53,12 +53,5 @@ <groupId>commons-cli</groupId> <artifactId>commons-cli</artifactId> </dependency> - <dependency> - <groupId>org.apache.openmeetings</groupId> - <artifactId>openmeetings-util</artifactId> - <version>${project.version}</version> - <type>test-jar</type> - <scope>test</scope> - </dependency> </dependencies> </project> diff --git a/openmeetings-install/src/test/java/module-info.test b/openmeetings-install/src/test/java/module-info.test deleted file mode 100644 index 7841b5f3c..000000000 --- a/openmeetings-install/src/test/java/module-info.test +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License") + you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -open module org.apache.openmeetings.install { - // This one should be in-sync with module-info.java - exports org.apache.openmeetings.backup; - exports org.apache.openmeetings.cli; - exports org.apache.openmeetings.installation; - - requires com.github.openjson; - - requires org.apache.commons.io; - requires org.apache.commons.lang3; - - requires org.apache.openjpa; - - requires org.apache.openmeetings.core; - requires org.apache.openmeetings.db; - requires org.apache.openmeetings.util; - - requires org.apache.wicket.core; - requires org.apache.wicket.request; - requires org.apache.wicket.util; - - requires jakarta.inject; - requires jakarta.xml.bind; - - requires spring.context; - requires spring.context.support; - requires spring.web; - - requires java.desktop; - requires commons.cli; - requires quartz; - requires xstream; - - requires org.slf4j; - - //tests - requires org.junit.jupiter.api; -} diff --git a/openmeetings-mediaserver/pom.xml b/openmeetings-mediaserver/pom.xml index a38173417..1a2758a1d 100644 --- a/openmeetings-mediaserver/pom.xml +++ b/openmeetings-mediaserver/pom.xml @@ -49,17 +49,10 @@ <groupId>org.kurento</groupId> <artifactId>kurento-client</artifactId> </dependency> - <dependency> - <groupId>org.apache.openmeetings</groupId> - <artifactId>openmeetings-util</artifactId> - <version>${project.version}</version> - <type>test-jar</type> - <scope>test</scope> - </dependency> </dependencies> <build> <plugins> - <!--plugin> + <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-javadoc-plugin</artifactId> <executions> @@ -76,10 +69,9 @@ <goals> <goal>javadoc-no-fork</goal> </goals> - <phase>generate-resources</phase> </execution> </executions> - </plugin--> + </plugin> </plugins> </build> </project> diff --git a/openmeetings-mediaserver/src/test/java/module-info.test b/openmeetings-mediaserver/src/test/java/module-info.test deleted file mode 100644 index 3234ebb9b..000000000 --- a/openmeetings-mediaserver/src/test/java/module-info.test +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License") + you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -open module org.apache.openmeetings.mediaserver { - // This one should be in-sync with module-info.java - exports org.apache.openmeetings.mediaserver; - - requires com.github.openjson; - - requires org.apache.commons.lang3; - - requires org.apache.openmeetings.core; - requires org.apache.openmeetings.db; - requires org.apache.openmeetings.util; - - requires org.apache.wicket.ioc; - requires org.apache.wicket.util; - - requires jakarta.annotation; - requires jakarta.inject; - - requires spring.beans; - requires spring.context; - requires spring.core; - - requires kurento.client; - requires kurento.jsonrpc.client; - requires kurento.commons; - requires com.google.gson; - - requires org.slf4j; - - //tests - requires org.junit.jupiter.api; -} diff --git a/openmeetings-screenshare/pom.xml b/openmeetings-screenshare/pom.xml index 05b9e9035..a36ccdac5 100644 --- a/openmeetings-screenshare/pom.xml +++ b/openmeetings-screenshare/pom.xml @@ -214,4 +214,3 @@ </plugins> </build> </project> - diff --git a/openmeetings-server/pom.xml b/openmeetings-server/pom.xml index 696978a04..e56f3c043 100644 --- a/openmeetings-server/pom.xml +++ b/openmeetings-server/pom.xml @@ -40,6 +40,7 @@ <om.webapp>webapps/openmeetings</om.webapp> <root.webapp>webapps/ROOT</root.webapp> <server-file.dir>web-server</server-file.dir> + <automatic-module-name>org.apache.openmeetings.server</automatic-module-name> </properties> <url>https://openmeetings.apache.org</url> <scm> diff --git a/openmeetings-install/pom.xml b/openmeetings-tests/pom.xml similarity index 60% copy from openmeetings-install/pom.xml copy to openmeetings-tests/pom.xml index 3e37d0ed7..0deadc56a 100644 --- a/openmeetings-install/pom.xml +++ b/openmeetings-tests/pom.xml @@ -25,40 +25,18 @@ <version>8.0.0-SNAPSHOT</version> <relativePath>..</relativePath> </parent> - <artifactId>openmeetings-install</artifactId> + <artifactId>openmeetings-tests</artifactId> <packaging>jar</packaging> - <name>Openmeetings Install</name> - <description>Module for OpenMeetings command line admin and classes necessary for installer.</description> + <name>Openmeetings Tests</name> + <description>Module for common test classes</description> <properties> <site.basedir>${project.parent.basedir}</site.basedir> </properties> <dependencies> <dependency> - <groupId>org.springframework</groupId> - <artifactId>spring-context-support</artifactId> - </dependency> - <dependency> - <groupId>org.springframework</groupId> - <artifactId>spring-core</artifactId> - </dependency> - <dependency> - <groupId>org.quartz-scheduler</groupId> - <artifactId>quartz</artifactId> - </dependency> - <dependency> - <groupId>org.apache.openmeetings</groupId> - <artifactId>openmeetings-core</artifactId> - </dependency> - <dependency> - <groupId>commons-cli</groupId> - <artifactId>commons-cli</artifactId> - </dependency> - <dependency> - <groupId>org.apache.openmeetings</groupId> - <artifactId>openmeetings-util</artifactId> - <version>${project.version}</version> - <type>test-jar</type> - <scope>test</scope> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter-api</artifactId> + <scope>compile</scope> </dependency> </dependencies> </project> diff --git a/openmeetings-util/src/main/java/org/apache/openmeetings/util/logging/TimedDatabase.java b/openmeetings-tests/src/main/java/module-info.java similarity index 72% copy from openmeetings-util/src/main/java/org/apache/openmeetings/util/logging/TimedDatabase.java copy to openmeetings-tests/src/main/java/module-info.java index 028029551..60d0547a5 100644 --- a/openmeetings-util/src/main/java/org/apache/openmeetings/util/logging/TimedDatabase.java +++ b/openmeetings-tests/src/main/java/module-info.java @@ -1,5 +1,4 @@ /* - * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information @@ -17,15 +16,8 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.openmeetings.util.logging; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -public @interface TimedDatabase { +module org.apache.openmeetings.tests { + exports org.apache.openmeetings.test; + requires org.junit.jupiter.api; } diff --git a/openmeetings-util/src/test/java/org/apache/openmeetings/test/NonJenkinsTest.java b/openmeetings-tests/src/main/java/org/apache/openmeetings/test/NonJenkinsTest.java similarity index 100% rename from openmeetings-util/src/test/java/org/apache/openmeetings/test/NonJenkinsTest.java rename to openmeetings-tests/src/main/java/org/apache/openmeetings/test/NonJenkinsTest.java diff --git a/openmeetings-util/pom.xml b/openmeetings-util/pom.xml index b4388d9a5..8f99a8388 100644 --- a/openmeetings-util/pom.xml +++ b/openmeetings-util/pom.xml @@ -38,17 +38,6 @@ <groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> </plugin> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-jar-plugin</artifactId> - <executions> - <execution> - <goals> - <goal>test-jar</goal> - </goals> - </execution> - </executions> - </plugin> </plugins> <resources> <resource> @@ -132,7 +121,12 @@ </dependency> <dependency> <groupId>io.prometheus</groupId> - <artifactId>simpleclient_servlet_jakarta</artifactId> + <artifactId>prometheus-metrics-core</artifactId> + </dependency> + + <dependency> + <groupId>org.apache.openmeetings</groupId> + <artifactId>openmeetings-tests</artifactId> </dependency> </dependencies> </project> diff --git a/openmeetings-util/src/main/java/module-info.java b/openmeetings-util/src/main/java/module-info.java index 72e073b16..12b8d3ca4 100644 --- a/openmeetings-util/src/main/java/module-info.java +++ b/openmeetings-util/src/main/java/module-info.java @@ -45,7 +45,9 @@ module org.apache.openmeetings.util { requires org.mnode.ical4j.core; requires org.aspectj.tools; requires org.dom4j; - requires simpleclient; requires ch.qos.logback.classic; requires ch.qos.logback.core; + + requires prometheus.metrics.core; + requires prometheus.metrics.model; } diff --git a/openmeetings-util/src/main/java/org/apache/openmeetings/util/logging/PrometheusAspect.java b/openmeetings-util/src/main/java/org/apache/openmeetings/util/logging/PrometheusAspect.java index 396f5ae50..258f0e3e1 100644 --- a/openmeetings-util/src/main/java/org/apache/openmeetings/util/logging/PrometheusAspect.java +++ b/openmeetings-util/src/main/java/org/apache/openmeetings/util/logging/PrometheusAspect.java @@ -24,21 +24,27 @@ import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.stereotype.Component; -import io.prometheus.client.Histogram; +import io.prometheus.metrics.core.metrics.Histogram; +import io.prometheus.metrics.model.snapshots.Unit; @Aspect @Component public class PrometheusAspect { + private static final Histogram histogram = Histogram.builder() + .help("OpenMeetings Application Metrics") + .name("org_openmeetings_metrics") + .labelNames("class", "method", "type", "message") + .register(); private Object logExecutionTime(ProceedingJoinPoint joinPoint, String logType) throws Throwable { String className = joinPoint.getSignature().getDeclaringType().getSimpleName(); String methodName = joinPoint.getSignature().getName(); - Histogram.Timer timer = PrometheusUtil.getHistogram() // - .labels(className, methodName, logType, "default").startTimer(); + long start = System.nanoTime(); try { return joinPoint.proceed(); } finally { - timer.observeDuration(); + histogram.labelValues(className, methodName, logType, "default") + .observe(Unit.nanosToSeconds(System.nanoTime() - start)); } } diff --git a/openmeetings-util/src/main/java/org/apache/openmeetings/util/logging/PrometheusUtil.java b/openmeetings-util/src/main/java/org/apache/openmeetings/util/logging/PrometheusUtil.java deleted file mode 100644 index 0f1cfd3f0..000000000 --- a/openmeetings-util/src/main/java/org/apache/openmeetings/util/logging/PrometheusUtil.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License") + you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.openmeetings.util.logging; - -import io.prometheus.client.Histogram; - -public class PrometheusUtil { - private static final Histogram histogram = Histogram.build() - .help("OpenMeetings Application Metrics") - .name("org_openmeetings_metrics") - .labelNames("class", "method", "type", "message") - .register(); - - private PrometheusUtil() { - } - - public static Histogram getHistogram() { - return histogram; - } -} diff --git a/openmeetings-util/src/main/java/org/apache/openmeetings/util/logging/TimedApplication.java b/openmeetings-util/src/main/java/org/apache/openmeetings/util/logging/TimedApplication.java index 09c25ea7a..b5d23fae2 100644 --- a/openmeetings-util/src/main/java/org/apache/openmeetings/util/logging/TimedApplication.java +++ b/openmeetings-util/src/main/java/org/apache/openmeetings/util/logging/TimedApplication.java @@ -27,5 +27,4 @@ import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface TimedApplication { - } diff --git a/openmeetings-util/src/main/java/org/apache/openmeetings/util/logging/TimedDatabase.java b/openmeetings-util/src/main/java/org/apache/openmeetings/util/logging/TimedDatabase.java index 028029551..cdbe750b8 100644 --- a/openmeetings-util/src/main/java/org/apache/openmeetings/util/logging/TimedDatabase.java +++ b/openmeetings-util/src/main/java/org/apache/openmeetings/util/logging/TimedDatabase.java @@ -27,5 +27,4 @@ import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface TimedDatabase { - } diff --git a/openmeetings-util/src/test/java/module-info.test b/openmeetings-util/src/test/java/module-info.test deleted file mode 100644 index 3ea1b258b..000000000 --- a/openmeetings-util/src/test/java/module-info.test +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License") + you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -open module org.apache.openmeetings.util { - // This one should be in-sync with module-info.java - exports org.apache.openmeetings.util; - exports org.apache.openmeetings.util.crypt; - exports org.apache.openmeetings.util.mail; - exports org.apache.openmeetings.util.process; - exports org.apache.openmeetings.util.ws; - exports org.apache.openmeetings.util.logging; - - requires jakarta.activation; - requires jakarta.servlet; - - requires com.github.openjson; - - requires org.apache.commons.codec; - requires org.apache.commons.lang3; - - requires org.apache.tika.core; - - requires org.apache.wicket.util; - requires org.apache.wicket.core; - requires org.apache.wicket.extensions; - - requires org.slf4j; - requires spring.context; - - requires org.bouncycastle.provider; - requires org.mnode.ical4j.core; - requires org.aspectj.tools; - requires org.dom4j; - requires simpleclient; - requires ch.qos.logback.classic; - requires ch.qos.logback.core; - - //tests - requires transitive org.junit.jupiter.engine; - requires transitive org.junit.jupiter.api; -} diff --git a/openmeetings-web/pom.xml b/openmeetings-web/pom.xml index 5cc6c4d42..48dceb1ab 100644 --- a/openmeetings-web/pom.xml +++ b/openmeetings-web/pom.xml @@ -476,17 +476,7 @@ <!-- Test dependencies --> <dependency> <groupId>org.apache.openmeetings</groupId> - <artifactId>openmeetings-util</artifactId> - <version>${project.version}</version> - <type>test-jar</type> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.apache.openmeetings</groupId> - <artifactId>openmeetings-core</artifactId> - <version>${project.version}</version> - <type>test-jar</type> - <scope>test</scope> + <artifactId>openmeetings-tests</artifactId> </dependency> <dependency> <groupId>org.apache.cxf</groupId> @@ -521,5 +511,9 @@ <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-params</artifactId> </dependency> + <dependency> + <groupId>io.prometheus</groupId> + <artifactId>prometheus-metrics-exporter-servlet-jakarta</artifactId> + </dependency> </dependencies> </project> diff --git a/openmeetings-web/src/main/java/module-info.java b/openmeetings-web/src/main/java/module-info.java index e793d828e..78eefd4db 100644 --- a/openmeetings-web/src/main/java/module-info.java +++ b/openmeetings-web/src/main/java/module-info.java @@ -74,7 +74,6 @@ module org.apache.openmeetings.web { requires com.hazelcast.core; requires org.danekja.jdk.serializable.functional; - requires simpleclient.servlet.jakarta; requires xstream; requires spring.beans; @@ -83,4 +82,8 @@ module org.apache.openmeetings.web { requires spring.web; requires org.slf4j; + + requires prometheus.metrics.core; + requires prometheus.metrics.model; + requires prometheus.metrics.exporter.servlet.jakarta; } diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/logging/OpenMeetingsMetricsServlet.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/logging/OpenMeetingsMetricsServlet.java index f068ddbbc..f45e2040a 100644 --- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/logging/OpenMeetingsMetricsServlet.java +++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/logging/OpenMeetingsMetricsServlet.java @@ -18,14 +18,27 @@ */ package org.apache.openmeetings.web.util.logging; -import io.prometheus.client.servlet.jakarta.exporter.MetricsServlet; +import java.io.IOException; -public class OpenMeetingsMetricsServlet extends MetricsServlet { +import org.springframework.stereotype.Service; + +import io.prometheus.metrics.exporter.servlet.jakarta.PrometheusMetricsServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +@Service +public class OpenMeetingsMetricsServlet extends PrometheusMetricsServlet { private static final long serialVersionUID = 1L; + private final TomcatStats stats; public OpenMeetingsMetricsServlet() { super(); - new TomcatGenericExports(false).register(); + stats = new TomcatStats(false); } + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { + stats.refresh(); + super.doGet(request, response); + } } diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/logging/TomcatGenericExports.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/logging/TomcatGenericExports.java deleted file mode 100644 index 5403b53b2..000000000 --- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/logging/TomcatGenericExports.java +++ /dev/null @@ -1,324 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License") + you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.openmeetings.web.util.logging; - -import java.io.InputStream; -import java.lang.management.ManagementFactory; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Properties; -import java.util.Set; - -import javax.management.Attribute; -import javax.management.AttributeList; -import javax.management.MBeanServer; -import javax.management.ObjectInstance; -import javax.management.ObjectName; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import io.prometheus.client.Collector; -import io.prometheus.client.CounterMetricFamily; -import io.prometheus.client.GaugeMetricFamily; - -/** - * Exports Tomcat metrics applicable to most most applications: - * - * - http session metrics - request processor metrics - thread pool metrics - * - * Example usage: - * - * <pre> - * {@code - * new TomcatGenericExports(false).register(); - * } - * </pre> - * - * Example metrics being exported: - * - * <pre> - * tomcat_info{version="7.0.61.0",build="Apr 29 2015 14:58:03 UTC",} 1.0 - * tomcat_session_active_total{context="/foo",host="default",} 877.0 - * tomcat_session_rejected_total{context="/foo",host="default",} 0.0 - * tomcat_session_created_total{context="/foo",host="default",} 24428.0 - * tomcat_session_expired_total{context="/foo",host="default",} 23832.0 - * tomcat_session_alivetime_seconds_avg{context="/foo",host="default",} 633.0 - * tomcat_session_alivetime_seconds_max{context="/foo",host="default",} 9883.0 - * tomcat_requestprocessor_received_bytes{name="http-bio-0.0.0.0-8080",} 0.0 - * tomcat_requestprocessor_sent_bytes{name="http-bio-0.0.0.0-8080",} 5056098.0 - * tomcat_requestprocessor_time_seconds{name="http-bio-0.0.0.0-8080",} 127386.0 - * tomcat_requestprocessor_error_count{name="http-bio-0.0.0.0-8080",} 0.0 - * tomcat_requestprocessor_request_count{name="http-bio-0.0.0.0-8080",} 33709.0 - * tomcat_threads_total{pool="http-bio-0.0.0.0-8080",} 10.0 - * tomcat_threads_active_total{pool="http-bio-0.0.0.0-8080",} 2.0 - * tomcat_threads_active_max{pool="http-bio-0.0.0.0-8080",} 200.0 - * </pre> - */ -public class TomcatGenericExports extends Collector { - private static final Logger log = LoggerFactory.getLogger(TomcatGenericExports.class); - private static final String LABEL_NAME = "name"; - private String jmxDomain = "Catalina"; - - public TomcatGenericExports(boolean embedded) { - if (embedded) { - jmxDomain = "Tomcat"; - } - } - - private void addRequestProcessorMetrics(List<MetricFamilySamples> mfs) { - try { - final MBeanServer server = ManagementFactory.getPlatformMBeanServer(); - ObjectName filterName = new ObjectName(jmxDomain + ":type=GlobalRequestProcessor,name=*"); - Set<ObjectInstance> mBeans = server.queryMBeans(filterName, null); - - if (!mBeans.isEmpty()) { - List<String> labelNameList = List.of(LABEL_NAME); - - GaugeMetricFamily requestProcessorBytesReceivedGauge = new GaugeMetricFamily( - "tomcat_requestprocessor_received_bytes", "Number of bytes received by this request processor", - labelNameList); - - GaugeMetricFamily requestProcessorBytesSentGauge = new GaugeMetricFamily( - "tomcat_requestprocessor_sent_bytes", "Number of bytes sent by this request processor", - labelNameList); - - GaugeMetricFamily requestProcessorProcessingTimeGauge = new GaugeMetricFamily( - "tomcat_requestprocessor_time_seconds", "The total time spend by this request processor", - labelNameList); - - CounterMetricFamily requestProcessorErrorCounter = new CounterMetricFamily( - "tomcat_requestprocessor_error_count", - "The number of error request served by this request processor", labelNameList); - - CounterMetricFamily requestProcessorRequestCounter = new CounterMetricFamily( - "tomcat_requestprocessor_request_count", - "The number of request served by this request processor", labelNameList); - - for (final ObjectInstance mBean : mBeans) { - List<String> labelValueList = Collections - .singletonList(mBean.getObjectName().getKeyProperty("name").replaceAll("[\"\\\\]", "")); - - requestProcessorBytesReceivedGauge.addMetric(labelValueList, - ((Long) server.getAttribute(mBean.getObjectName(), "bytesReceived")).doubleValue()); - - requestProcessorBytesSentGauge.addMetric(labelValueList, - ((Long) server.getAttribute(mBean.getObjectName(), "bytesSent")).doubleValue()); - - requestProcessorProcessingTimeGauge.addMetric(labelValueList, - ((Long) server.getAttribute(mBean.getObjectName(), "processingTime")).doubleValue() - / 1000.0); - - requestProcessorErrorCounter.addMetric(labelValueList, - ((Integer) server.getAttribute(mBean.getObjectName(), "errorCount")).doubleValue()); - - requestProcessorRequestCounter.addMetric(labelValueList, - ((Integer) server.getAttribute(mBean.getObjectName(), "requestCount")).doubleValue()); - } - - mfs.add(requestProcessorBytesReceivedGauge); - mfs.add(requestProcessorBytesSentGauge); - mfs.add(requestProcessorProcessingTimeGauge); - mfs.add(requestProcessorRequestCounter); - mfs.add(requestProcessorErrorCounter); - } - } catch (Exception e) { - log.error("Error retrieving metric.", e); - } - } - - private void addSessionMetrics(List<MetricFamilySamples> mfs) { - try { - final MBeanServer server = ManagementFactory.getPlatformMBeanServer(); - ObjectName filterName = new ObjectName(jmxDomain + ":type=Manager,context=*,host=*"); - Set<ObjectInstance> mBeans = server.queryMBeans(filterName, null); - - if (!mBeans.isEmpty()) { - List<String> labelNameList = List.of("host", "context"); - - GaugeMetricFamily activeSessionCountGauge = new GaugeMetricFamily("tomcat_session_active_total", - "Number of active sessions", labelNameList); - - GaugeMetricFamily rejectedSessionCountGauge = new GaugeMetricFamily("tomcat_session_rejected_total", - "Number of sessions rejected due to maxActive being reached", labelNameList); - - GaugeMetricFamily createdSessionCountGauge = new GaugeMetricFamily("tomcat_session_created_total", - "Number of sessions created", labelNameList); - - GaugeMetricFamily expiredSessionCountGauge = new GaugeMetricFamily("tomcat_session_expired_total", - "Number of sessions that expired", labelNameList); - - GaugeMetricFamily sessionAvgAliveTimeGauge = new GaugeMetricFamily( - "tomcat_session_alivetime_seconds_avg", "Average time an expired session had been alive", - labelNameList); - - GaugeMetricFamily sessionMaxAliveTimeGauge = new GaugeMetricFamily( - "tomcat_session_alivetime_seconds_max", "Maximum time an expired session had been alive", - labelNameList); - - GaugeMetricFamily contextStateGauge = new GaugeMetricFamily("tomcat_context_state_started", - "Indication if the lifecycle state of this context is STARTED", labelNameList); - - for (final ObjectInstance mBean : mBeans) { - List<String> labelValueList = List.of(mBean.getObjectName().getKeyProperty("host"), - mBean.getObjectName().getKeyProperty("context")); - - activeSessionCountGauge.addMetric(labelValueList, - ((Integer) server.getAttribute(mBean.getObjectName(), "activeSessions")).doubleValue()); - - rejectedSessionCountGauge.addMetric(labelValueList, - ((Integer) server.getAttribute(mBean.getObjectName(), "rejectedSessions")).doubleValue()); - - createdSessionCountGauge.addMetric(labelValueList, - ((Long) server.getAttribute(mBean.getObjectName(), "sessionCounter")).doubleValue()); - - expiredSessionCountGauge.addMetric(labelValueList, - ((Long) server.getAttribute(mBean.getObjectName(), "expiredSessions")).doubleValue()); - - sessionAvgAliveTimeGauge.addMetric(labelValueList, - ((Integer) server.getAttribute(mBean.getObjectName(), "sessionAverageAliveTime")) - .doubleValue()); - - sessionMaxAliveTimeGauge.addMetric(labelValueList, - ((Integer) server.getAttribute(mBean.getObjectName(), "sessionMaxAliveTime")) - .doubleValue()); - - if (server.getAttribute(mBean.getObjectName(), "stateName").equals("STARTED")) { - contextStateGauge.addMetric(labelValueList, 1.0); - } else { - contextStateGauge.addMetric(labelValueList, 0.0); - } - } - - mfs.add(activeSessionCountGauge); - mfs.add(rejectedSessionCountGauge); - mfs.add(createdSessionCountGauge); - mfs.add(expiredSessionCountGauge); - mfs.add(sessionAvgAliveTimeGauge); - mfs.add(sessionMaxAliveTimeGauge); - mfs.add(contextStateGauge); - } - } catch (Exception e) { - log.error("Error retrieving metric.", e); - } - } - - private void addThreadPoolMetrics(List<MetricFamilySamples> mfs) { - try { - final MBeanServer server = ManagementFactory.getPlatformMBeanServer(); - ObjectName filterName = new ObjectName(jmxDomain + ":type=ThreadPool,name=*"); - Set<ObjectInstance> mBeans = server.queryMBeans(filterName, null); - - if (!mBeans.isEmpty()) { - List<String> labelList = List.of(LABEL_NAME); - - GaugeMetricFamily threadPoolCurrentCountGauge = new GaugeMetricFamily("tomcat_threads_total", - "Number threads in this pool.", labelList); - - GaugeMetricFamily threadPoolActiveCountGauge = new GaugeMetricFamily("tomcat_threads_active_total", - "Number of active threads in this pool.", labelList); - - GaugeMetricFamily threadPoolMaxThreadsGauge = new GaugeMetricFamily("tomcat_threads_max", - "Maximum number of threads allowed in this pool.", labelList); - - GaugeMetricFamily threadPoolConnectionCountGauge = new GaugeMetricFamily( - "tomcat_connections_active_total", "Number of connections served by this pool.", labelList); - - GaugeMetricFamily threadPoolMaxConnectionGauge = new GaugeMetricFamily("tomcat_connections_active_max", - "Maximum number of concurrent connections served by this pool.", labelList); - - String[] genericAttributes = new String[] { "currentThreadCount", "currentThreadsBusy", "maxThreads", - "connectionCount", "maxConnections" }; - - for (final ObjectInstance mBean : mBeans) { - List<String> labelValueList = Collections - .singletonList(mBean.getObjectName().getKeyProperty("name").replaceAll("[\"\\\\]", "")); - AttributeList attributeList = server.getAttributes(mBean.getObjectName(), genericAttributes); - for (Attribute attribute : attributeList.asList()) { - switch (attribute.getName()) { - case "currentThreadCount": - threadPoolCurrentCountGauge.addMetric(labelValueList, - ((Integer) attribute.getValue()).doubleValue()); - break; - case "currentThreadsBusy": - threadPoolActiveCountGauge.addMetric(labelValueList, - ((Integer) attribute.getValue()).doubleValue()); - break; - case "maxThreads": - threadPoolMaxThreadsGauge.addMetric(labelValueList, - ((Integer) attribute.getValue()).doubleValue()); - break; - case "connectionCount": - threadPoolConnectionCountGauge.addMetric(labelValueList, - ((Long) attribute.getValue()).doubleValue()); - break; - case "maxConnections": - threadPoolMaxConnectionGauge.addMetric(labelValueList, - ((Integer) attribute.getValue()).doubleValue()); - break; - default: - log.warn("Unexpected attribute {}", attribute); - break; - } - } - } - - addNonEmptyMetricFamily(mfs, threadPoolCurrentCountGauge); - addNonEmptyMetricFamily(mfs, threadPoolActiveCountGauge); - addNonEmptyMetricFamily(mfs, threadPoolMaxThreadsGauge); - addNonEmptyMetricFamily(mfs, threadPoolConnectionCountGauge); - addNonEmptyMetricFamily(mfs, threadPoolMaxConnectionGauge); - } - } catch (Exception e) { - log.error("Error retrieving metric: {}", e.getMessage()); - } - } - - private void addVersionInfo(List<MetricFamilySamples> mfs) { - GaugeMetricFamily tomcatInfo = new GaugeMetricFamily("tomcat_info", "tomcat version info", - List.of("version", "build")); - try (InputStream is = getClass().getResourceAsStream("/org/apache/catalina/util/ServerInfo.properties")) { - Properties props = new Properties(); - props.load(is); - //server info can be get as props.getProperty("server.info"); - tomcatInfo.addMetric(List.of(props.getProperty("server.number"), props.getProperty("server.built")), 1); - } catch (Exception t) { - log.warn("Unable to read Tomcat version: ", t); - } - mfs.add(tomcatInfo); - } - - private void addNonEmptyMetricFamily(List<MetricFamilySamples> mfs, GaugeMetricFamily metricFamily) { - if (!metricFamily.samples.isEmpty()) { - mfs.add(metricFamily); - } - } - - @Override - public List<MetricFamilySamples> collect() { - List<MetricFamilySamples> mfs = new ArrayList<>(); - addSessionMetrics(mfs); - addThreadPoolMetrics(mfs); - addRequestProcessorMetrics(mfs); - addVersionInfo(mfs); - return mfs; - - } -} diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/logging/TomcatStats.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/logging/TomcatStats.java new file mode 100644 index 000000000..cd1f9842d --- /dev/null +++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/util/logging/TomcatStats.java @@ -0,0 +1,314 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License") + you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.openmeetings.web.util.logging; + +import java.io.InputStream; +import java.lang.management.ManagementFactory; +import java.util.Properties; +import java.util.Set; + +import javax.management.Attribute; +import javax.management.AttributeList; +import javax.management.AttributeNotFoundException; +import javax.management.InstanceNotFoundException; +import javax.management.MBeanException; +import javax.management.MBeanServer; +import javax.management.ObjectInstance; +import javax.management.ObjectName; +import javax.management.ReflectionException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.prometheus.metrics.core.metrics.Gauge; + +/** + * Exports Tomcat metrics applicable to most applications: + * + * - http session metrics - request processor metrics - thread pool metrics + * + * Example usage: + * + * <pre> + * {@code + * TomcatStats stats = new TomcatStats(false); + * stats.refresh(); + * } + * </pre> + * + * Example metrics being exported: + * + * <pre> + * tomcat_info{version="7.0.61.0",build="Apr 29 2015 14:58:03 UTC",} 1.0 + * tomcat_session_active{context="/foo",host="default",} 877.0 + * tomcat_session_rejected{context="/foo",host="default",} 0.0 + * tomcat_session_constructed{context="/foo",host="default",} 24428.0 + * tomcat_session_expired{context="/foo",host="default",} 23832.0 + * tomcat_session_alivetime_seconds_avg{context="/foo",host="default",} 633.0 + * tomcat_session_alivetime_seconds_max{context="/foo",host="default",} 9883.0 + * tomcat_requestprocessor_received_bytes{name="http-bio-0.0.0.0-8080",} 0.0 + * tomcat_requestprocessor_sent_bytes{name="http-bio-0.0.0.0-8080",} 5056098.0 + * tomcat_requestprocessor_time_seconds{name="http-bio-0.0.0.0-8080",} 127386.0 + * tomcat_requestprocessor_error_count{name="http-bio-0.0.0.0-8080",} 0.0 + * tomcat_requestprocessor_request_count{name="http-bio-0.0.0.0-8080",} 33709.0 + * tomcat_threads{pool="http-bio-0.0.0.0-8080",} 10.0 + * tomcat_threads_active{pool="http-bio-0.0.0.0-8080",} 2.0 + * tomcat_threads_active_max{pool="http-bio-0.0.0.0-8080",} 200.0 + * </pre> + */ + +public class TomcatStats { + private static final Logger log = LoggerFactory.getLogger(TomcatStats.class); + + private static final String[] LBL_NAMES = new String[]{"name"}; + private static final Gauge rqBytesReceived = Gauge.builder() + .name("tomcat_requestprocessor_received_bytes") + .help("Number of bytes received by this request processor") + .labelNames(LBL_NAMES) + .register(); + private static final Gauge rqBytesSent = Gauge.builder() + .name("tomcat_requestprocessor_sent_bytes") + .help("Number of bytes sent by this request processor") + .labelNames(LBL_NAMES) + .register(); + private static final Gauge rqTime = Gauge.builder() + .name("tomcat_requestprocessor_time_seconds") + .help("The total time spend by this request processor") + .labelNames(LBL_NAMES) + .register(); + private static final Gauge rqErrors = Gauge.builder() + .name("tomcat_requestprocessor_error_count") + .help("The number of error request served by this request processor") + .labelNames(LBL_NAMES) + .register(); + private static final Gauge rqRequests = Gauge.builder() + .name("tomcat_requestprocessor_request_count") + .help("The number of request served by this request processor") + .labelNames(LBL_NAMES) + .register(); + + private static final Gauge threads = Gauge.builder() + .name("tomcat_threads") + .help("Number threads in this pool.") + .labelNames(LBL_NAMES) + .register(); + private static final Gauge threadsActive = Gauge.builder() + .name("tomcat_threads_active") + .help("Number of active threads in this pool.") + .labelNames(LBL_NAMES) + .register(); + private static final Gauge threadsMax = Gauge.builder() + .name("tomcat_threads_max") + .help("Maximum number of threads allowed in this pool.") + .labelNames(LBL_NAMES) + .register(); + private static final Gauge connsActive = Gauge.builder() + .name("tomcat_connections_active") + .help("Number of connections served by this pool.") + .labelNames(LBL_NAMES) + .register(); + private static final Gauge connsActiveMax = Gauge.builder() + .name("tomcat_connections_active_max") + .help("Maximum number of concurrent connections served by this pool.") + .labelNames(LBL_NAMES) + .register(); + + private static final String[] SESSION_LBL_NAMES = new String[]{"host", "context"}; + private static final Gauge sessionActive = Gauge.builder() + .name("tomcat_session_active") + .help("Number of active sessions") + .labelNames(SESSION_LBL_NAMES) + .register(); + private static final Gauge sessionRejected = Gauge.builder() + .name("tomcat_session_rejected") + .help("Number of sessions rejected due to maxActive being reached") + .labelNames(SESSION_LBL_NAMES) + .register(); + private static final Gauge sessionCreated = Gauge.builder() + .name("tomcat_session_constructed") + .help("Number of sessions created") + .labelNames(SESSION_LBL_NAMES) + .register(); + private static final Gauge sessionExpired = Gauge.builder() + .name("tomcat_session_expired") + .help("Number of sessions that expired") + .labelNames(SESSION_LBL_NAMES) + .register(); + private static final Gauge sessionAvgAlive = Gauge.builder() + .name("tomcat_session_alivetime_seconds_avg") + .help("Average time an expired session had been alive") + .labelNames(SESSION_LBL_NAMES) + .register(); + private static final Gauge sessionMaxAlive = Gauge.builder() + .name("tomcat_session_alivetime_seconds_max") + .help("Maximum time an expired session had been alive") + .labelNames(SESSION_LBL_NAMES) + .register(); + private static final Gauge ctxState = Gauge.builder() + .name("tomcat_context_state_started") + .help("Indication if the lifecycle state of this context is STARTED") + .labelNames(SESSION_LBL_NAMES) + .register(); + + private static final Gauge version = Gauge.builder() + .name("tomcat_details") + .help("tomcat version info") + .labelNames("version", "build") + .register(); + + private final String jmxDomain; + + public TomcatStats(boolean embedded) { + jmxDomain = embedded ? "Tomcat" : "Catalina"; + } + + private double getAttr(Attribute attribute) { + return ((Number)attribute.getValue()).doubleValue(); + } + + private double getAttr(final MBeanServer server, final ObjectInstance mBean, String attr) throws InstanceNotFoundException, AttributeNotFoundException, ReflectionException, MBeanException { + return ((Number)server.getAttribute(mBean.getObjectName(), attr)).doubleValue(); + } + + private void updateRequestProcessorMetrics() { + try { + final MBeanServer server = ManagementFactory.getPlatformMBeanServer(); + ObjectName filterName = new ObjectName(jmxDomain + ":type=GlobalRequestProcessor,name=*"); + Set<ObjectInstance> mBeans = server.queryMBeans(filterName, null); + + for (final ObjectInstance mBean : mBeans) { + String labels = mBean.getObjectName().getKeyProperty("name").replaceAll("[\"\\\\]", ""); + + rqBytesReceived.labelValues(labels) + .set(getAttr(server, mBean, "bytesReceived")); + + rqBytesSent.labelValues(labels) + .set(getAttr(server, mBean, "bytesSent")); + + rqTime.labelValues(labels) + .set(getAttr(server, mBean, "processingTime") / 1000.0); + + rqErrors.labelValues(labels) + .set(getAttr(server, mBean, "errorCount")); + + rqRequests.labelValues(labels) + .set(getAttr(server, mBean, "requestCount")); + } + } catch (Exception e) { + log.error("Error retrieving RequestProcessor metric.", e); + } + } + + private void updateSessionMetrics() { + try { + final MBeanServer server = ManagementFactory.getPlatformMBeanServer(); + ObjectName filterName = new ObjectName(jmxDomain + ":type=Manager,context=*,host=*"); + Set<ObjectInstance> mBeans = server.queryMBeans(filterName, null); + + for (final ObjectInstance mBean : mBeans) { + String[] labelValues = new String[] { + mBean.getObjectName().getKeyProperty("host") + , mBean.getObjectName().getKeyProperty("context")}; + + sessionActive.labelValues(labelValues) + .set(getAttr(server, mBean, "activeSessions")); + + sessionRejected.labelValues(labelValues) + .set(getAttr(server, mBean, "rejectedSessions")); + + sessionCreated.labelValues(labelValues) + .set(getAttr(server, mBean, "sessionCounter")); + + sessionExpired.labelValues(labelValues) + .set(getAttr(server, mBean, "expiredSessions")); + + sessionAvgAlive.labelValues(labelValues) + .set(getAttr(server, mBean, "sessionAverageAliveTime")); + + sessionMaxAlive.labelValues(labelValues) + .set(getAttr(server, mBean, "sessionMaxAliveTime")); + + ctxState.labelValues(labelValues) + .set("STARTED".equals(server.getAttribute(mBean.getObjectName(), "stateName")) ? 1. : 0.); + } + } catch (Exception e) { + log.error("Error retrieving Session metric.", e); + } + } + + private void updateThreadPoolMetrics() { + try { + final MBeanServer server = ManagementFactory.getPlatformMBeanServer(); + ObjectName filterName = new ObjectName(jmxDomain + ":type=ThreadPool,name=*"); + Set<ObjectInstance> mBeans = server.queryMBeans(filterName, null); + + if (!mBeans.isEmpty()) { + String[] genericAttributes = new String[] { "currentThreadCount", "currentThreadsBusy", "maxThreads", + "connectionCount", "maxConnections" }; + + for (final ObjectInstance mBean : mBeans) { + String label = mBean.getObjectName().getKeyProperty("name").replaceAll("[\"\\\\]", ""); + AttributeList attributeList = server.getAttributes(mBean.getObjectName(), genericAttributes); + for (Attribute attribute : attributeList.asList()) { + switch (attribute.getName()) { + case "currentThreadCount": + threads.labelValues(label).set(getAttr(attribute)); + break; + case "currentThreadsBusy": + threadsActive.labelValues(label).set(getAttr(attribute)); + break; + case "maxThreads": + threadsMax.labelValues(label).set(getAttr(attribute)); + break; + case "connectionCount": + connsActive.labelValues(label).set(getAttr(attribute)); + break; + case "maxConnections": + connsActiveMax.labelValues(label).set(getAttr(attribute)); + break; + default: + log.warn("Unexpected attribute {}", attribute); + break; + } + } + } + } + } catch (Exception e) { + log.error("Error retrieving ThreadPool metric: {}", e.getMessage()); + } + } + + private void updateVersionInfo() { + try (InputStream is = getClass().getResourceAsStream("/org/apache/catalina/util/ServerInfo.properties")) { + Properties props = new Properties(); + props.load(is); + //server info can be get as props.getProperty("server.info"); + version.labelValues(props.getProperty("server.number"), props.getProperty("server.built")).set(1.); + } catch (Exception t) { + log.warn("Unable to read Tomcat version: ", t); + } + } + + public void refresh() { + updateRequestProcessorMetrics(); + updateSessionMetrics(); + updateThreadPoolMetrics(); + updateVersionInfo(); + } +} diff --git a/openmeetings-web/src/main/webapp/WEB-INF/classes/applicationContext.xml b/openmeetings-web/src/main/webapp/WEB-INF/classes/applicationContext.xml index a069c52cd..d3503511c 100644 --- a/openmeetings-web/src/main/webapp/WEB-INF/classes/applicationContext.xml +++ b/openmeetings-web/src/main/webapp/WEB-INF/classes/applicationContext.xml @@ -41,7 +41,7 @@ <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" /> <!-- Start annotation Prometheus metrics <aop:aspectj-autoproxy/> - End annotation --> + End annotation --> <context:annotation-config /> <context:component-scan base-package="org.apache.openmeetings" /> diff --git a/openmeetings-web/src/main/webapp/WEB-INF/web.xml b/openmeetings-web/src/main/webapp/WEB-INF/web.xml index 7dbe3091b..769f299b4 100644 --- a/openmeetings-web/src/main/webapp/WEB-INF/web.xml +++ b/openmeetings-web/src/main/webapp/WEB-INF/web.xml @@ -57,34 +57,6 @@ </init-param> </filter> - <!-- Start Prometheus Filter HTTP Servlet metrics - <filter> - <filter-name>prometheusFilter</filter-name> - <filter-class>io.prometheus.client.servlet.jakarta.filter.MetricsFilter</filter-class> - <init-param> - <param-name>metric-name</param-name> - <param-value>webapp_metrics_filter</param-value> - </init-param> - <init-param> - <param-name>help</param-name> - <param-value>This is the help for your metrics filter</param-value> - </init-param> - <init-param> - <param-name>buckets</param-name> - <param-value>0.005,0.01,0.025,0.05,0.075,0.1,0.25,0.5,0.75,1,2.5,5,7.5,10</param-value> - </init-param> - <init-param> - <param-name>path-components</param-name> - <param-value>0</param-value> - </init-param> - </filter> - - <filter-mapping> - <filter-name>prometheusFilter</filter-name> - <url-pattern>/*</url-pattern> - </filter-mapping> - End Prometheus --> - <filter-mapping> <filter-name>OpenmeetingsApplication</filter-name> <url-pattern>/*</url-pattern> @@ -94,6 +66,17 @@ <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> + <!-- Start Prometheus export metrics HTTP + <servlet> + <servlet-name>metrics</servlet-name> + <servlet-class>org.apache.openmeetings.web.util.logging.OpenMeetingsMetricsServlet</servlet-class> + </servlet> + <servlet-mapping> + <servlet-name>metrics</servlet-name> + <url-pattern>/services/metrics/</url-pattern> + </servlet-mapping> + End Prometheus --> + <servlet> <servlet-name>CXFServlet</servlet-name> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> @@ -109,17 +92,6 @@ <url-pattern>/services/*</url-pattern> </servlet-mapping> - <!-- Start Prometheus export metrics HTTP - <servlet> - <servlet-name>metrics</servlet-name> - <servlet-class>org.apache.openmeetings.web.util.logging.OpenMeetingsMetricsServlet</servlet-class> - </servlet> - <servlet-mapping> - <servlet-name>metrics</servlet-name> - <url-pattern>/services/metrics/</url-pattern> - </servlet-mapping> - End Prometheus --> - <mime-mapping> <extension>inc</extension> <mime-type>text/plain</mime-type> diff --git a/openmeetings-web/src/test/java/module-info.test b/openmeetings-web/src/test/java/module-info.test deleted file mode 100644 index 428ba6791..000000000 --- a/openmeetings-web/src/test/java/module-info.test +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License") + you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -open module org.apache.openmeetings.web { - // This one should be in-sync with module-info.java - requires org.apache.openmeetings.core; - requires org.apache.openmeetings.db; - requires org.apache.openmeetings.install; - requires org.apache.openmeetings.mediaserver; - requires org.apache.openmeetings.service; - requires org.apache.openmeetings.util; - requires org.apache.openmeetings.webservice; - - requires com.github.openjson; - - requires totp; - - requires org.apache.commons.io; - requires org.apache.commons.fileupload2.core; - requires org.apache.commons.fileupload2.jakarta; - requires org.apache.commons.lang3; - - requires org.apache.openjpa; - - requires org.apache.httpcomponents.httpclient; - - requires org.apache.wicket.auth.roles; - requires org.apache.wicket.core; - requires org.apache.wicket.devutils; - requires org.apache.wicket.extensions; - requires org.apache.wicket.ioc; - requires org.apache.wicket.request; - requires org.apache.wicket.spring; - requires org.apache.wicket.util; - requires org.apache.wicket.websocket.core; - - requires wicketstuff.dashboard.core; - requires wicketstuff.datastore.hazelcast; - requires wicketstuff.select2; - requires wicketstuff.urlfragment; - requires jqplot; - requires jqplot4java; - requires wicket.bootstrap.extensions; - requires wicket.bootstrap.core; - requires wicket.bootstrap.themes; - requires wicket.webjars; - requires wicket.jquery.ui; - requires wicket.jquery.ui.calendar; - requires wicket.jquery.ui.core; - requires wicket.jquery.ui.plugins; - - requires jakarta.annotation; - requires jakarta.inject; - requires jakarta.servlet; - requires jakarta.websocket.client; - requires jakarta.ws.rs; - - requires java.net.http; - requires java.management; - requires java.sql; - - requires com.hazelcast.core; - requires org.danekja.jdk.serializable.functional; - requires simpleclient.servlet.jakarta; - requires xstream; - - requires spring.beans; - requires spring.context; - requires spring.orm; - requires spring.web; - - requires org.slf4j; - - //tests - requires org.junit.jupiter.api; -} diff --git a/openmeetings-webservice/pom.xml b/openmeetings-webservice/pom.xml index acb255775..34409e16d 100644 --- a/openmeetings-webservice/pom.xml +++ b/openmeetings-webservice/pom.xml @@ -34,7 +34,7 @@ </properties> <build> <plugins> - <!--plugin> + <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-javadoc-plugin</artifactId> <executions> @@ -51,10 +51,9 @@ <goals> <goal>javadoc-no-fork</goal> </goals> - <phase>generate-resources</phase> </execution> </executions> - </plugin--> + </plugin> <plugin> <groupId>io.openapitools.swagger</groupId> <artifactId>swagger-maven-plugin</artifactId> @@ -196,12 +195,5 @@ <groupId>io.swagger.core.v3</groupId> <artifactId>swagger-annotations</artifactId> </dependency> - <dependency> - <groupId>org.apache.openmeetings</groupId> - <artifactId>openmeetings-util</artifactId> - <version>${project.version}</version> - <type>test-jar</type> - <scope>test</scope> - </dependency> </dependencies> </project> diff --git a/openmeetings-webservice/src/test/java/module-info.test b/openmeetings-webservice/src/test/java/module-info.test deleted file mode 100644 index d1c1fe2b3..000000000 --- a/openmeetings-webservice/src/test/java/module-info.test +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License") + you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -open module org.apache.openmeetings.webservice { - // This one should be in-sync with module-info.java - exports org.apache.openmeetings.webservice.util; - - requires org.apache.openmeetings.core; - requires org.apache.openmeetings.db; - requires org.apache.openmeetings.service; - requires org.apache.openmeetings.util; - - requires com.github.openjson; - requires org.apache.commons.lang3; - - requires jakarta.annotation; - requires jakarta.inject; - requires jakarta.jws; - requires jakarta.servlet; - requires jakarta.xml.ws; - requires jakarta.ws.rs; - - requires org.apache.cxf.core; - requires org.apache.cxf.frontend.jaxrs; - - requires org.apache.pdfbox; - - requires org.apache.wicket.core; - requires org.apache.wicket.extensions; - requires org.apache.wicket.util; - - requires io.swagger.v3.oas.annotations; - requires java.desktop; - - requires spring.beans; - requires spring.context; - - requires org.slf4j; - - //tests - requires org.junit.jupiter.api; -} diff --git a/pom.xml b/pom.xml index be8b36bb1..6763e8fb5 100644 --- a/pom.xml +++ b/pom.xml @@ -91,7 +91,7 @@ <tomcat.version>10.1.13</tomcat.version> <ical4j.version>4.0.0-beta9</ical4j.version> <cxf.version>4.0.3</cxf.version> - <io.prometheus.version>0.16.0</io.prometheus.version> + <io.prometheus.version>1.0.0</io.prometheus.version> <aspectjtools.version>1.9.20.1</aspectjtools.version> <simple-xml.version>2.7.1</simple-xml.version> <jettison.version>1.5.4</jettison.version> @@ -452,6 +452,12 @@ <artifactId>openmeetings-webservice</artifactId> <version>${project.version}</version> </dependency> + <dependency> + <groupId>org.apache.openmeetings</groupId> + <artifactId>openmeetings-tests</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> <dependency> <groupId>org.apache.openmeetings</groupId> <artifactId>openmeetings-util</artifactId> @@ -570,7 +576,12 @@ </dependency> <dependency> <groupId>io.prometheus</groupId> - <artifactId>simpleclient_servlet_jakarta</artifactId> + <artifactId>prometheus-metrics-core</artifactId> + <version>${io.prometheus.version}</version> + </dependency> + <dependency> + <groupId>io.prometheus</groupId> + <artifactId>prometheus-metrics-exporter-servlet-jakarta</artifactId> <version>${io.prometheus.version}</version> </dependency> <dependency> @@ -1159,6 +1170,36 @@ </execution> </executions> </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-source-plugin</artifactId> + <configuration> + <skip>${om.quick.build}</skip> + </configuration> + <executions> + <execution> + <id>attach-sources</id> + <goals> + <goal>jar</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-javadoc-plugin</artifactId> + <configuration> + <skip>${om.quick.build}</skip> + </configuration> + <executions> + <execution> + <id>attach-javadocs</id> + <goals> + <goal>jar</goal> + </goals> + </execution> + </executions> + </plugin> </plugins> <pluginManagement> <plugins> @@ -1169,7 +1210,6 @@ <doclint>none</doclint> <additionalOptions>-html5</additionalOptions> <source>${jdk.version}</source> - <javadocVersion>${jdk.version}</javadocVersion> <notimestamp>true</notimestamp> <links> <link>https://openmeetings.apache.org/openmeetings-db/apidocs/</link> @@ -1274,9 +1314,13 @@ <excludes> <exclude/> </excludes> + <argLine>@{argLine} --add-modules java.se --add-exports java.base/jdk.internal.ref=ALL-UNNAMED + --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.nio=ALL-UNNAMED + --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.management/sun.management=ALL-UNNAMED + --add-opens jdk.management/com.sun.management.internal=ALL-UNNAMED + --add-opens java.base/java.util=ALL-UNNAMED --add-opens=java.base/sun.security.util=ALL-UNNAMED + --add-opens=java.base/sun.security.x509=ALL-UNNAMED</argLine> <useModulePath>false</useModulePath> - <!--argLine>-Xint ${argLine}</argLine--> - <argLine>@{argLine} --add-modules java.se --add-exports java.base/jdk.internal.ref=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.management/sun.management=ALL-UNNAMED --add-opens jdk.management/com.sun.management.internal=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens=java.base/sun.security.util=ALL-UNNAMED --add-opens=java.base/sun.security.x509=A [...] </configuration> </plugin> <plugin> @@ -1709,6 +1753,7 @@ <activeByDefault>true</activeByDefault> </activation> <modules> + <module>openmeetings-tests</module> <module>openmeetings-util</module> <module>openmeetings-db</module> <module>openmeetings-core</module> @@ -1740,33 +1785,6 @@ </properties> <build> <plugins> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-source-plugin</artifactId> - <executions> - <execution> - <id>attach-sources</id> - <goals> - <goal>jar</goal> - </goals> - </execution> - </executions> - </plugin> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-javadoc-plugin</artifactId> - <configuration> - <skip>false</skip> - </configuration> - <executions> - <execution> - <id>attach-javadocs</id> - <goals> - <goal>jar</goal> - </goals> - </execution> - </executions> - </plugin> <plugin> <groupId>net.nicoulaj.maven.plugins</groupId> <artifactId>checksum-maven-plugin</artifactId>