Skip to content

Commit

Permalink
[#9631] Add exceptionTrace Module
Browse files Browse the repository at this point in the history
  • Loading branch information
intr3p1d committed May 10, 2023
1 parent c393a6c commit 8751c7a
Show file tree
Hide file tree
Showing 48 changed files with 2,833 additions and 3 deletions.
46 changes: 46 additions & 0 deletions exceptiontrace/exceptiontrace-collector/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>pinpoint-exceptiontrace-module</artifactId>
<groupId>com.navercorp.pinpoint</groupId>
<version>2.6.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>pinpoint-exceptiontrace-collector</artifactId>

<properties>
<jdk.version>11</jdk.version>
<jdk.home>${env.JAVA_11_HOME}</jdk.home>
</properties>

<dependencies>
<dependency>
<groupId>com.navercorp.pinpoint</groupId>
<artifactId>pinpoint-pinot-kafka</artifactId>
</dependency>
<dependency>
<groupId>com.navercorp.pinpoint</groupId>
<artifactId>pinpoint-exceptiontrace-common</artifactId>
</dependency>
<dependency>
<groupId>com.navercorp.pinpoint</groupId>
<artifactId>pinpoint-metric</artifactId>
</dependency>
<dependency>
<groupId>com.navercorp.pinpoint</groupId>
<artifactId>pinpoint-commons-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
<version>2.9.4</version>
</dependency>
<dependency>
<groupId>com.navercorp.pinpoint</groupId>
<artifactId>pinpoint-collector</artifactId>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright 2023 NAVER Corp.
*
* Licensed 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 com.navercorp.pinpoint.exceptiontrace.collector;

import com.navercorp.pinpoint.exceptiontrace.collector.config.ExceptionMetricKafkaConfiguration;
import com.navercorp.pinpoint.pinot.config.PinotConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Profile;
import org.springframework.context.annotation.PropertySource;

/**
* @author intr3p1d
*/
@Profile("exception")
@Configuration
@Import({PinotConfiguration.class, ExceptionMetricKafkaConfiguration.class})
@ComponentScan({"com.navercorp.pinpoint.exceptiontrace.collector.service", "com.navercorp.pinpoint.exceptiontrace.collector.dao"})
@PropertySource({ExceptionTraceCollectorConfig.KAFKA_TOPIC_PROPERTIES})
public class ExceptionTraceCollectorConfig {
public static final String KAFKA_TOPIC_PROPERTIES = "classpath:profiles/${pinpoint.profiles.active}/kafka-topic-exception.properties";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright 2023 NAVER Corp.
*
* Licensed 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 com.navercorp.pinpoint.exceptiontrace.collector;

/**
* @author intr3p1d
*/
public class ExceptionTraceCollectorPropertySources {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright 2023 NAVER Corp.
*
* Licensed 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 com.navercorp.pinpoint.exceptiontrace.collector.config;

import com.navercorp.pinpoint.exceptiontrace.collector.model.SpanEventExceptionVo;
import com.navercorp.pinpoint.pinot.kafka.KafkaConfiguration;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.core.ProducerFactory;

/**
* @author intr3p1d
*/
@Configuration
@Import({KafkaConfiguration.class})
public class ExceptionMetricKafkaConfiguration {

@Bean
public KafkaTemplate<String, SpanEventExceptionVo> kafkaSpanEventExceptionTemplate(@Qualifier("kafkaProducerFactory") ProducerFactory producerFactory) {
return new KafkaTemplate<String, SpanEventExceptionVo>(producerFactory);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright 2023 NAVER Corp.
*
* Licensed 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 com.navercorp.pinpoint.exceptiontrace.collector.dao;

import com.navercorp.pinpoint.exceptiontrace.common.model.SpanEventException;

import java.util.List;

/**
* @author intr3p1d
*/
public interface ExceptionTraceDao {
void insert(List<SpanEventException> spanEventException);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright 2023 NAVER Corp.
*
* Licensed 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 com.navercorp.pinpoint.exceptiontrace.collector.dao;

import com.navercorp.pinpoint.exceptiontrace.collector.model.SpanEventExceptionVo;
import com.navercorp.pinpoint.exceptiontrace.common.model.SpanEventException;
import com.navercorp.pinpoint.exceptiontrace.common.util.StringPrecondition;
import com.navercorp.pinpoint.pinot.kafka.util.KafkaCallbacks;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.support.SendResult;
import org.springframework.stereotype.Repository;
import org.springframework.util.concurrent.ListenableFuture;
import org.springframework.util.concurrent.ListenableFutureCallback;

import java.util.List;
import java.util.Objects;

/**
* @author intr3p1d
*/
@Repository
public class PinotExceptionTraceDao implements ExceptionTraceDao {
private final Logger logger = LogManager.getLogger(this.getClass());

private final KafkaTemplate<String, SpanEventExceptionVo> kafkaSpanEventExceptionTemplate;

private final String topic;

private final ListenableFutureCallback<SendResult<String, SpanEventExceptionVo>> resultCallback
= KafkaCallbacks.loggingCallback("Kafka(SpanEventExceptionVo)", logger);


public PinotExceptionTraceDao(@Qualifier("kafkaSpanEventExceptionTemplate") KafkaTemplate<String, SpanEventExceptionVo> kafkaSpanEventExceptionTemplate,
@Value("${kafka.exception.topic}") String topic) {
this.kafkaSpanEventExceptionTemplate = Objects.requireNonNull(kafkaSpanEventExceptionTemplate, "kafkaSpanEventExceptionTemplate");
this.topic = StringPrecondition.requireHasLength(topic, "topic");
}

@Override
public void insert(List<SpanEventException> spanEventExceptions) {
Objects.requireNonNull(spanEventExceptions);
logger.info("Pinot data insert: {}", spanEventExceptions.toString());

for (SpanEventException spanEventException : spanEventExceptions) {
ListenableFuture<SendResult<String, SpanEventExceptionVo>> response = this.kafkaSpanEventExceptionTemplate.send(
topic, SpanEventExceptionVo.valueOf(spanEventException)
);
response.addCallback(resultCallback);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/*
* Copyright 2023 NAVER Corp.
*
* Licensed 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 com.navercorp.pinpoint.exceptiontrace.collector.model;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.navercorp.pinpoint.exceptiontrace.common.model.SpanEventException;
import com.navercorp.pinpoint.exceptiontrace.common.model.StackTraceElementWrapper;

import java.util.ArrayList;
import java.util.List;

/**
* @author intr3p1d
*/
public class SpanEventExceptionVo {

private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

private final SpanEventException spanEventException;
private List<String> stackTrace;


public SpanEventExceptionVo(
SpanEventException spanEventException
) {
this.spanEventException = spanEventException;
}

public static SpanEventExceptionVo valueOf(SpanEventException spanEventException) {
return new SpanEventExceptionVo(
spanEventException
);
}

private static List<String> toJsonString(List<StackTraceElementWrapper> stackTrace) {
List<String> strings = new ArrayList<>();
stackTrace.forEach(
(StackTraceElementWrapper s) -> {
try {
strings.add(OBJECT_MAPPER.writeValueAsString(s));
} catch (JsonProcessingException ignored) {
// do nothing
}
}
);
return strings;
}

public long getTimestamp() {
return this.spanEventException.getTimestamp();
}

public String getTransactionId() {
return this.spanEventException.getTransactionId();
}

public long getSpanId() {
return this.spanEventException.getSpanId();
}

public long getExceptionId() {
return this.spanEventException.getExceptionId();
}

public String getApplicationServiceType() {
return this.spanEventException.getApplicationServiceType();
}

public String getApplicationName() {
return this.spanEventException.getApplicationName();
}

public String getAgentId() {
return this.spanEventException.getAgentId();
}

public String getUriTemplate() {
return this.spanEventException.getUriTemplate();
}

public String getErrorClassName() {
return this.spanEventException.getErrorClassName();
}

public String getErrorMessage() {
return this.spanEventException.getErrorMessage();
}

public int getExceptionDepth() {
return this.spanEventException.getExceptionDepth();
}

public List<String> getStackTrace() {
if (stackTrace == null) {
stackTrace = toJsonString(this.spanEventException.getStackTrace());
}
return stackTrace;
}

public String getStackTraceHash() {
return this.spanEventException.getStackTraceHash();
}

@Override
public String toString() {
return "SpanEventExceptionVo{" +
"spanEventException=" + spanEventException +
", stackTrace=" + stackTrace +
'}';
}
}
Loading

0 comments on commit 8751c7a

Please sign in to comment.