Skip to content

Commit 4901131

Browse files
committed
[pinpoint-apm#10776] Add open telemetry metric web
1 parent ae60f37 commit 4901131

File tree

30 files changed

+1497
-6
lines changed

30 files changed

+1497
-6
lines changed

otlpmetric/otlpmetric-collector/src/main/java/com/navercorp/pinpoint/otlp/collector/controller/OpenTelemetryMetricController.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
import com.navercorp.pinpoint.otlp.collector.mapper.OtlpMetricMapper;
2020
import com.navercorp.pinpoint.otlp.collector.model.OtlpMetricData;
21-
import com.navercorp.pinpoint.otlp.collector.service.OtlpMetricService;
21+
import com.navercorp.pinpoint.otlp.collector.service.OtlpMetricCollectorService;
2222
import com.navercorp.pinpoint.pinot.tenant.TenantProvider;
2323
import io.opentelemetry.proto.collector.metrics.v1.ExportMetricsServiceRequest;
2424
import io.opentelemetry.proto.common.v1.KeyValue;
@@ -44,15 +44,15 @@ public class OpenTelemetryMetricController {
4444
private final Logger logger = LogManager.getLogger(this.getClass());
4545

4646
private final String tenantId;
47-
@NotNull private final OtlpMetricService otlpMetricService;
47+
@NotNull private final OtlpMetricCollectorService otlpMetricCollectorService;
4848
@NotNull private final OtlpMetricMapper otlpMetricMapper;
4949

5050
public OpenTelemetryMetricController(TenantProvider tenantProvider,
51-
@Valid OtlpMetricService otlpMetricService,
51+
@Valid OtlpMetricCollectorService otlpMetricCollectorService,
5252
@Valid OtlpMetricMapper otlpMetricDataMapper) {
5353
Objects.requireNonNull(tenantProvider, "tenantProvider");
5454
this.tenantId = tenantProvider.getTenantId();
55-
this.otlpMetricService = Objects.requireNonNull(otlpMetricService, "otlpMetricService");
55+
this.otlpMetricCollectorService = Objects.requireNonNull(otlpMetricCollectorService, "otlpMetricService");
5656
this.otlpMetricMapper = Objects.requireNonNull(otlpMetricDataMapper, "otlpMetricDataMapper");
5757
this.otlpMetricMapper.setTenantId(tenantId);
5858
}
@@ -70,7 +70,7 @@ public ResponseEntity<Void> saveOtelMetric(@RequestBody ExportMetricsServiceRequ
7070
List<Metric> metricList = scopeMetrics.getMetricsList();
7171
for (Metric metric: metricList) {
7272
OtlpMetricData metricData = toMetrics(metric, tags);
73-
otlpMetricService.save(metricData);
73+
otlpMetricCollectorService.save(metricData);
7474

7575
if (logger.isDebugEnabled()) {
7676
logger.debug("tenantId:{} serviceNamespace:{} serviceName:{} metricGroupName:{} metricName: {}",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.navercorp.pinpoint.otlp.common.model;
2+
3+
public enum AggreTemporality {
4+
5+
UNSPECIFIED(0),
6+
DELTA(1),
7+
CUMULATIVE(2),
8+
UNRECOGNIZED(-1);
9+
10+
private final int value;
11+
public final int getNumber() {
12+
return this.value;
13+
}
14+
15+
public static AggreTemporality forNumber(int value) {
16+
switch (value) {
17+
case 0:
18+
return UNSPECIFIED;
19+
case 1:
20+
return DELTA;
21+
case 2:
22+
return CUMULATIVE;
23+
default:
24+
return UNRECOGNIZED;
25+
}
26+
}
27+
28+
public static AggreTemporality forName(String name) {
29+
switch(name.toUpperCase()) {
30+
case "UNSPECIFIED":
31+
return UNSPECIFIED;
32+
case "DELTA":
33+
return DELTA;
34+
case "CUMULATIVE":
35+
return CUMULATIVE;
36+
default:
37+
return UNRECOGNIZED;
38+
}
39+
}
40+
41+
private AggreTemporality(int value) {
42+
this.value = value;
43+
}
44+
}

otlpmetric/otlpmetric-web/pom.xml

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
<parent>
7+
<groupId>com.navercorp.pinpoint</groupId>
8+
<artifactId>pinpoint-otlpmetric</artifactId>
9+
<version>3.0.0-SNAPSHOT</version>
10+
</parent>
11+
12+
<artifactId>pinpoint-otlpmetric-web</artifactId>
13+
<properties>
14+
<jdk.version>17</jdk.version>
15+
<jdk.home>${env.JAVA_17_HOME}</jdk.home>
16+
</properties>
17+
<dependencies>
18+
<dependency>
19+
<groupId>org.springframework.boot</groupId>
20+
<artifactId>spring-boot-autoconfigure</artifactId>
21+
<version>3.1.8</version>
22+
</dependency>
23+
<dependency>
24+
<groupId>com.navercorp.pinpoint</groupId>
25+
<artifactId>pinpoint-pinot-config</artifactId>
26+
</dependency>
27+
<dependency>
28+
<groupId>com.navercorp.pinpoint</groupId>
29+
<artifactId>pinpoint-datasource</artifactId>
30+
</dependency>
31+
<dependency>
32+
<groupId>org.springframework</groupId>
33+
<artifactId>spring-web</artifactId>
34+
<version>6.0.16</version>
35+
</dependency>
36+
<dependency>
37+
<groupId>jakarta.validation</groupId>
38+
<artifactId>jakarta.validation-api</artifactId>
39+
<version>3.0.2</version>
40+
</dependency>
41+
<dependency>
42+
<groupId>com.navercorp.pinpoint</groupId>
43+
<artifactId>pinpoint-metric</artifactId>
44+
</dependency>
45+
<dependency>
46+
<groupId>com.navercorp.pinpoint</groupId>
47+
<artifactId>pinpoint-otlpmetric-common</artifactId>
48+
</dependency>
49+
</dependencies>
50+
51+
</project>
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package com.navercorp.pinpoint.otlp.web;
2+
3+
import com.navercorp.pinpoint.otlp.common.model.AggreFunc;
4+
import com.navercorp.pinpoint.otlp.common.model.AggreTemporality;
5+
import com.navercorp.pinpoint.otlp.common.model.DataType;
6+
import com.navercorp.pinpoint.otlp.web.vo.FieldAttribute;
7+
import org.apache.ibatis.type.JdbcType;
8+
import org.apache.ibatis.type.TypeHandler;
9+
import org.apache.logging.log4j.LogManager;
10+
import org.apache.logging.log4j.Logger;
11+
12+
import java.sql.CallableStatement;
13+
import java.sql.PreparedStatement;
14+
import java.sql.ResultSet;
15+
import java.sql.SQLException;
16+
17+
public class FieldAttributeHandler implements TypeHandler<FieldAttribute> {
18+
private final Logger logger = LogManager.getLogger(this.getClass());
19+
20+
@Override
21+
public void setParameter(PreparedStatement ps, int i, FieldAttribute parameter, JdbcType jdbcType) throws SQLException {
22+
throw new UnsupportedOperationException("FieldAttribute is only used for result.");
23+
}
24+
25+
@Override
26+
public FieldAttribute getResult(ResultSet rs, String columnName) throws SQLException {
27+
return parseResult(rs);
28+
}
29+
30+
@Override
31+
public FieldAttribute getResult(ResultSet rs, int columnIndex) throws SQLException {
32+
return parseResult(rs);
33+
}
34+
35+
@Override
36+
public FieldAttribute getResult(CallableStatement cs, int columnIndex) throws SQLException {
37+
return parseResult(cs);
38+
}
39+
40+
private FieldAttribute parseResult(ResultSet rs) {
41+
try {
42+
String fieldName = rs.getString("fieldName");
43+
DataType dataType = DataType.forNumber(rs.getInt("dataType"));
44+
AggreFunc aggreFunc = AggreFunc.forNumber(rs.getInt("aggreFunc"));
45+
AggreTemporality aggreTemporality = AggreTemporality.forNumber(rs.getInt("aggregationTemporality"));
46+
String description = rs.getString("description");
47+
String unit = rs.getString("unit");
48+
String version = rs.getString("version");
49+
return new FieldAttribute(fieldName, dataType, aggreFunc, aggreTemporality, description, unit, version);
50+
} catch (SQLException e) {
51+
logger.warn("FieldAttribute parsing error.");
52+
return null;
53+
}
54+
}
55+
private FieldAttribute parseResult(CallableStatement cs) {
56+
try {
57+
String fieldName = cs.getString("fieldName");
58+
DataType dataType = DataType.forNumber(cs.getInt("dataType"));
59+
AggreFunc aggreFunc = AggreFunc.forNumber(cs.getInt("aggreFunc"));
60+
AggreTemporality aggreTemporality = AggreTemporality.forNumber(cs.getInt("aggregationTemporality"));
61+
String description = cs.getString("description");
62+
String unit = cs.getString("unit");
63+
String version = cs.getString("version");
64+
return new FieldAttribute(fieldName, dataType, aggreFunc, aggreTemporality, description, unit, version);
65+
} catch (SQLException e) {
66+
logger.warn("FieldAttribute parsing error.");
67+
return null;
68+
}
69+
}
70+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package com.navercorp.pinpoint.otlp.web;/*
2+
* Copyright 2024 NAVER Corp.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import com.navercorp.pinpoint.datasource.MainDataSourcePropertySource;
18+
import com.navercorp.pinpoint.otlp.web.config.OtlpMetricWebPinotDaoConfiguration;
19+
import com.navercorp.pinpoint.pinot.config.PinotConfiguration;
20+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
21+
import org.springframework.context.annotation.ComponentScan;
22+
import org.springframework.context.annotation.Configuration;
23+
import org.springframework.context.annotation.Import;
24+
25+
@Configuration
26+
@ComponentScan({
27+
"com.navercorp.pinpoint.otlp.web.controller",
28+
"com.navercorp.pinpoint.otlp.web.service",
29+
"com.navercorp.pinpoint.otlp.web.dao"
30+
})
31+
@Import({
32+
MainDataSourcePropertySource.class,
33+
PinotConfiguration.class,
34+
OtlpMetricWebPinotDaoConfiguration.class
35+
})
36+
@ConditionalOnProperty(name = "pinpoint.modules.web.otlpmetric.enabled", havingValue = "true")
37+
public class OtlpMetricWebConfig {
38+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package com.navercorp.pinpoint.otlp.web.config;
2+
3+
import com.navercorp.pinpoint.mybatis.MyBatisConfigurationCustomizer;
4+
import com.navercorp.pinpoint.mybatis.MyBatisRegistryHandler;
5+
import org.apache.ibatis.session.SqlSessionFactory;
6+
import org.apache.ibatis.transaction.TransactionFactory;
7+
import org.apache.ibatis.transaction.managed.ManagedTransactionFactory;
8+
import org.mybatis.spring.SqlSessionFactoryBean;
9+
import org.mybatis.spring.SqlSessionTemplate;
10+
import org.springframework.beans.factory.FactoryBean;
11+
import org.springframework.beans.factory.annotation.Qualifier;
12+
import org.springframework.beans.factory.annotation.Value;
13+
import org.springframework.context.annotation.Bean;
14+
import org.springframework.context.annotation.Configuration;
15+
import org.springframework.core.io.Resource;
16+
17+
import javax.sql.DataSource;
18+
19+
@Configuration
20+
public class OtlpMetricWebPinotDaoConfiguration {
21+
22+
@Bean
23+
public FactoryBean<SqlSessionFactory> otlpMetricPinotSessionFactory(
24+
@Qualifier("pinotConfigurationCustomizer") MyBatisConfigurationCustomizer customizer,
25+
@Qualifier("pinotDataSource") DataSource dataSource,
26+
@Value("classpath:mapper/otlpmetric/*Mapper.xml") Resource[] mappers) {
27+
SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
28+
29+
sessionFactoryBean.setDataSource(dataSource);
30+
31+
org.apache.ibatis.session.Configuration config = new org.apache.ibatis.session.Configuration();
32+
customizer.customize(config);
33+
registryHandler(config);
34+
sessionFactoryBean.setConfiguration(config);
35+
36+
sessionFactoryBean.setMapperLocations(mappers);
37+
sessionFactoryBean.setFailFast(true);
38+
sessionFactoryBean.setTransactionFactory(transactionFactory());
39+
40+
41+
return sessionFactoryBean;
42+
}
43+
44+
private TransactionFactory transactionFactory() {
45+
return new ManagedTransactionFactory();
46+
}
47+
48+
private void registryHandler(org.apache.ibatis.session.Configuration config) {
49+
MyBatisRegistryHandler registryHandler = new OtlpMetricWebRegistryHandler();
50+
registryHandler.registerTypeAlias(config.getTypeAliasRegistry());
51+
registryHandler.registerTypeHandler(config.getTypeHandlerRegistry());
52+
}
53+
54+
@Bean
55+
public SqlSessionTemplate otlpMetricPinotSessionTemplate(
56+
@Qualifier("otlpMetricPinotSessionFactory") SqlSessionFactory sessionFactory) {
57+
return new SqlSessionTemplate(sessionFactory);
58+
}
59+
60+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package com.navercorp.pinpoint.otlp.web.config;
2+
3+
import com.navercorp.pinpoint.mybatis.MyBatisRegistryHandler;
4+
import com.navercorp.pinpoint.otlp.common.model.AggreFunc;
5+
import com.navercorp.pinpoint.otlp.common.model.DataType;
6+
import com.navercorp.pinpoint.otlp.web.vo.handler.FieldAttributeHandler;
7+
import com.navercorp.pinpoint.otlp.web.vo.*;
8+
import org.apache.ibatis.type.TypeAliasRegistry;
9+
import org.apache.ibatis.type.TypeHandlerRegistry;
10+
11+
public class OtlpMetricWebRegistryHandler implements MyBatisRegistryHandler {
12+
@Override
13+
public void registerTypeAlias(TypeAliasRegistry typeAliasRegistry) {
14+
typeAliasRegistry.registerAlias(OtlpMetricGroupsQueryParam.class);
15+
typeAliasRegistry.registerAlias(OtlpMetricNamesQueryParam.class);
16+
typeAliasRegistry.registerAlias(OtlpMetricDetailsQueryParam.class);
17+
typeAliasRegistry.registerAlias(FieldAttribute.class);
18+
typeAliasRegistry.registerAlias(OtlpMetricChartQueryParameter.class);
19+
typeAliasRegistry.registerAlias(OtlpMetricChartResult.class);
20+
typeAliasRegistry.registerAlias(AggreFunc.class);
21+
typeAliasRegistry.registerAlias(DataType.class);
22+
typeAliasRegistry.registerAlias(OtlpMetricChartSummary.class);
23+
}
24+
25+
@Override
26+
public void registerTypeHandler(TypeHandlerRegistry typeHandlerRegistry) {
27+
typeHandlerRegistry.register(FieldAttribute.class, FieldAttributeHandler.class);
28+
}
29+
}

0 commit comments

Comments
 (0)