Feature add clickhouse jdbc plugin (#41)
This commit is contained in:
parent
e99a031080
commit
813fc31bd2
|
|
@ -90,6 +90,7 @@ jobs:
|
|||
- oracle-scenario
|
||||
- druid-1.x-scenario
|
||||
- hikaricp-scenario
|
||||
- clickhouse-0.3.x-scenario
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ Release Notes.
|
|||
* Format SpringMVC & Tomcat EntrySpan operation name to `METHOD:URI`.
|
||||
* Make `HTTP method` in the operation name according to runtime, rather than previous code-level definition, which used to have possibilities including multiple HTTP methods.
|
||||
* Fix the bug that httpasyncclient-4.x-plugin does not take effect every time.
|
||||
* Add plugin to support ClickHouse JDBC driver.
|
||||
|
||||
#### Documentation
|
||||
|
||||
|
|
|
|||
|
|
@ -215,4 +215,5 @@ public class ComponentsDefine {
|
|||
|
||||
public static final OfficialComponent JACKSON = new OfficialComponent(118, "Jackson");
|
||||
|
||||
public static final OfficialComponent CLICKHOUSE_JDBC_DRIVER = new OfficialComponent(119, "ClickHouse-jdbc-driver");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,61 @@
|
|||
<!--
|
||||
~ 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.
|
||||
~
|
||||
-->
|
||||
|
||||
<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>apm-sdk-plugin</artifactId>
|
||||
<groupId>org.apache.skywalking</groupId>
|
||||
<version>8.8.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>apm-clickhouse-0.3.x-plugin</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>clickhouse-0.3.x-plugin</name>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<clickhouse.jdbc.version>0.3.1-patch</clickhouse.jdbc.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>ru.yandex.clickhouse</groupId>
|
||||
<artifactId>clickhouse-jdbc</artifactId>
|
||||
<version>${clickhouse.jdbc.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.skywalking</groupId>
|
||||
<artifactId>apm-jdbc-commons</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* 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.skywalking.apm.plugin.jdbc.clickhouse;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
|
||||
import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
|
||||
import ru.yandex.clickhouse.ClickHouseConnectionImpl;
|
||||
import ru.yandex.clickhouse.ClickHouseStatement;
|
||||
|
||||
/**
|
||||
* This interceptor is used to replace {@link org.apache.skywalking.apm.plugin.jdbc.JDBCStatementInterceptor}.
|
||||
* Because return value type of {@link ClickHouseConnectionImpl#createStatement()} method is {@link
|
||||
* ru.yandex.clickhouse.ClickHouseStatement} instead of {@link java.sql.Statement}.
|
||||
*/
|
||||
public class ClickHouseStatementMethodInterceptor implements InstanceMethodsAroundInterceptor {
|
||||
|
||||
@Override
|
||||
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
|
||||
MethodInterceptResult result) throws Throwable {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
|
||||
Object ret) throws Throwable {
|
||||
final Object connectionInfo = objInst.getSkyWalkingDynamicField();
|
||||
if (connectionInfo == null) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return new TracedClickHouseStatement((ClickHouseStatement) ret, (ConnectionInfo) connectionInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
|
||||
Class<?>[] argumentsTypes, Throwable t) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* 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.skywalking.apm.plugin.jdbc.clickhouse;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import org.apache.skywalking.apm.agent.core.context.ContextManager;
|
||||
import org.apache.skywalking.apm.agent.core.context.tag.Tags;
|
||||
import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
|
||||
import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
|
||||
import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class ClickHouseStatementTracingWrapper {
|
||||
|
||||
public static <T> T of(ConnectionInfo connectionInfo, String methodName, String sql,
|
||||
SupplierWithException<T> supplier) throws SQLException {
|
||||
final AbstractSpan span = ContextManager.createExitSpan(
|
||||
connectionInfo.getDBType() + "/JDBI/Statement/" + methodName, connectionInfo.getDatabasePeer());
|
||||
try {
|
||||
Tags.DB_TYPE.set(span, "sql");
|
||||
Tags.DB_INSTANCE.set(span, connectionInfo.getDatabaseName());
|
||||
Tags.DB_STATEMENT.set(span, sql);
|
||||
span.setComponent(connectionInfo.getComponent());
|
||||
SpanLayer.asDB(span);
|
||||
return supplier.get();
|
||||
} catch (SQLException e) {
|
||||
span.log(e);
|
||||
throw e;
|
||||
} finally {
|
||||
ContextManager.stopSpan();
|
||||
}
|
||||
}
|
||||
|
||||
public interface SupplierWithException<T> {
|
||||
|
||||
T get() throws SQLException;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* 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.skywalking.apm.plugin.jdbc.clickhouse;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
|
||||
import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
|
||||
import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
|
||||
import ru.yandex.clickhouse.settings.ClickHouseProperties;
|
||||
|
||||
/**
|
||||
* Enhance {@link ru.yandex.clickhouse.ClickHouseConnectionImpl#initConnection(ClickHouseProperties)} method.
|
||||
* <p>
|
||||
* ClickHouse JDBC Driver uses this method to simulate the action of connecting database in JDBC protocol.
|
||||
* So this method is enhanced to prevent the generation of exit span of http type.
|
||||
* </p>
|
||||
* <p>
|
||||
* This interceptor is used to replace {@link org.apache.skywalking.apm.plugin.jdbc.JDBCDriverInterceptor}.
|
||||
* </p>
|
||||
*/
|
||||
public class InitConnectionMethodInterceptor implements InstanceMethodsAroundInterceptor {
|
||||
|
||||
@Override
|
||||
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
|
||||
MethodInterceptResult result) throws Throwable {
|
||||
final Object properties = allArguments[0];
|
||||
ClickHouseProperties clickHouseProperties = (ClickHouseProperties) properties;
|
||||
final ConnectionInfo connectionInfo = new ConnectionInfo(ComponentsDefine.CLICKHOUSE_JDBC_DRIVER,
|
||||
"ClickHouse", clickHouseProperties.getHost(), clickHouseProperties.getPort(),
|
||||
clickHouseProperties.getDatabase());
|
||||
objInst.setSkyWalkingDynamicField(connectionInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
|
||||
Object ret) throws Throwable {
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
|
||||
Class<?>[] argumentsTypes, Throwable t) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,407 @@
|
|||
/*
|
||||
* 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.skywalking.apm.plugin.jdbc.clickhouse;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.SQLWarning;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
|
||||
import ru.yandex.clickhouse.ClickHouseExternalData;
|
||||
import ru.yandex.clickhouse.ClickHouseStatement;
|
||||
import ru.yandex.clickhouse.Writer;
|
||||
import ru.yandex.clickhouse.response.ClickHouseResponse;
|
||||
import ru.yandex.clickhouse.response.ClickHouseResponseSummary;
|
||||
import ru.yandex.clickhouse.settings.ClickHouseQueryParam;
|
||||
import ru.yandex.clickhouse.util.ClickHouseRowBinaryInputStream;
|
||||
import ru.yandex.clickhouse.util.ClickHouseStreamCallback;
|
||||
|
||||
/**
|
||||
* The {@link ru.yandex.clickhouse.ClickHouseStatementImpl} instance wrapper.
|
||||
*/
|
||||
public class TracedClickHouseStatement implements ClickHouseStatement {
|
||||
|
||||
private final ClickHouseStatement delegate;
|
||||
private final ConnectionInfo connectionInfo;
|
||||
|
||||
public TracedClickHouseStatement(ClickHouseStatement delegate, ConnectionInfo connectionInfo) {
|
||||
this.delegate = delegate;
|
||||
this.connectionInfo = connectionInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClickHouseResponse executeQueryClickhouseResponse(String sql) throws SQLException {
|
||||
return ClickHouseStatementTracingWrapper.of(connectionInfo, "executeQueryClickhouseResponse", sql,
|
||||
() -> delegate.executeQueryClickhouseResponse(sql));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClickHouseResponse executeQueryClickhouseResponse(String sql,
|
||||
Map<ClickHouseQueryParam, String> additionalDBParams) throws SQLException {
|
||||
return ClickHouseStatementTracingWrapper.of(connectionInfo, "executeQueryClickhouseResponse", sql,
|
||||
() -> delegate.executeQueryClickhouseResponse(sql, additionalDBParams));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClickHouseResponse executeQueryClickhouseResponse(String sql,
|
||||
Map<ClickHouseQueryParam, String> additionalDBParams, Map<String, String> additionalRequestParams)
|
||||
throws SQLException {
|
||||
return ClickHouseStatementTracingWrapper.of(connectionInfo, "executeQueryClickhouseResponse", sql,
|
||||
() -> delegate.executeQueryClickhouseResponse(sql, additionalDBParams, additionalRequestParams));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClickHouseRowBinaryInputStream executeQueryClickhouseRowBinaryStream(String sql) throws SQLException {
|
||||
return ClickHouseStatementTracingWrapper.of(connectionInfo, "executeQueryClickhouseRowBinaryStream", sql,
|
||||
() -> delegate.executeQueryClickhouseRowBinaryStream(sql));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClickHouseRowBinaryInputStream executeQueryClickhouseRowBinaryStream(String sql,
|
||||
Map<ClickHouseQueryParam, String> additionalDBParams) throws SQLException {
|
||||
return ClickHouseStatementTracingWrapper.of(connectionInfo, "executeQueryClickhouseRowBinaryStream", sql,
|
||||
() -> delegate.executeQueryClickhouseRowBinaryStream(sql, additionalDBParams));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClickHouseRowBinaryInputStream executeQueryClickhouseRowBinaryStream(String sql,
|
||||
Map<ClickHouseQueryParam, String> additionalDBParams, Map<String, String> additionalRequestParams)
|
||||
throws SQLException {
|
||||
return ClickHouseStatementTracingWrapper.of(connectionInfo, "executeQueryClickhouseRowBinaryStream", sql,
|
||||
() -> delegate.executeQueryClickhouseRowBinaryStream(sql, additionalDBParams, additionalRequestParams));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet executeQuery(String sql, Map<ClickHouseQueryParam, String> additionalDBParams)
|
||||
throws SQLException {
|
||||
return ClickHouseStatementTracingWrapper.of(connectionInfo, "executeQuery", sql,
|
||||
() -> delegate.executeQuery(sql, additionalDBParams));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet executeQuery(String sql, Map<ClickHouseQueryParam, String> additionalDBParams,
|
||||
List<ClickHouseExternalData> externalData) throws SQLException {
|
||||
return ClickHouseStatementTracingWrapper.of(connectionInfo, "executeQuery", sql,
|
||||
() -> delegate.executeQuery(sql, additionalDBParams, externalData));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet executeQuery(String sql, Map<ClickHouseQueryParam, String> additionalDBParams,
|
||||
List<ClickHouseExternalData> externalData, Map<String, String> additionalRequestParams)
|
||||
throws SQLException {
|
||||
return ClickHouseStatementTracingWrapper.of(connectionInfo, "executeQuery", sql,
|
||||
() -> delegate.executeQuery(sql, additionalDBParams, externalData, additionalRequestParams));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendStream(InputStream content, String table, Map<ClickHouseQueryParam, String> additionalDBParams)
|
||||
throws SQLException {
|
||||
delegate.sendStream(content, table, additionalDBParams);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendStream(InputStream content, String table) throws SQLException {
|
||||
delegate.sendStream(content, table);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendRowBinaryStream(String sql, Map<ClickHouseQueryParam, String> additionalDBParams,
|
||||
ClickHouseStreamCallback callback) throws SQLException {
|
||||
sendRowBinaryStream(sql, additionalDBParams, callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendRowBinaryStream(String sql, ClickHouseStreamCallback callback) throws SQLException {
|
||||
sendRowBinaryStream(sql, callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendNativeStream(String sql, Map<ClickHouseQueryParam, String> additionalDBParams,
|
||||
ClickHouseStreamCallback callback) throws SQLException {
|
||||
sendNativeStream(sql, additionalDBParams, callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendNativeStream(String sql, ClickHouseStreamCallback callback) throws SQLException {
|
||||
sendNativeStream(sql, callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendCSVStream(InputStream content, String table, Map<ClickHouseQueryParam, String> additionalDBParams)
|
||||
throws SQLException {
|
||||
sendCSVStream(content, table, additionalDBParams);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendCSVStream(InputStream content, String table) throws SQLException {
|
||||
sendCSVStream(content, table);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendStreamSQL(InputStream content, String sql, Map<ClickHouseQueryParam, String> additionalDBParams)
|
||||
throws SQLException {
|
||||
sendStreamSQL(content, sql, additionalDBParams);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendStreamSQL(InputStream content, String sql) throws SQLException {
|
||||
sendStreamSQL(content, sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Writer write() {
|
||||
return delegate.write();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClickHouseResponseSummary getResponseSummary() {
|
||||
return delegate.getResponseSummary();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet executeQuery(String sql) throws SQLException {
|
||||
return ClickHouseStatementTracingWrapper.of(connectionInfo, "executeQuery", sql,
|
||||
() -> delegate.executeQuery(sql));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int executeUpdate(String sql) throws SQLException {
|
||||
return ClickHouseStatementTracingWrapper.of(connectionInfo, "executeUpdate", sql,
|
||||
() -> delegate.executeUpdate(sql));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws SQLException {
|
||||
delegate.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxFieldSize() throws SQLException {
|
||||
return delegate.getMaxFieldSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxFieldSize(int max) throws SQLException {
|
||||
delegate.setMaxFieldSize(max);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxRows() throws SQLException {
|
||||
return delegate.getMaxRows();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxRows(int max) throws SQLException {
|
||||
delegate.setMaxRows(max);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEscapeProcessing(boolean enable) throws SQLException {
|
||||
delegate.setEscapeProcessing(enable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getQueryTimeout() throws SQLException {
|
||||
return delegate.getQueryTimeout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setQueryTimeout(int seconds) throws SQLException {
|
||||
delegate.setQueryTimeout(seconds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() throws SQLException {
|
||||
delegate.cancel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLWarning getWarnings() throws SQLException {
|
||||
return delegate.getWarnings();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearWarnings() throws SQLException {
|
||||
delegate.clearWarnings();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCursorName(String name) throws SQLException {
|
||||
delegate.setCursorName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(String sql) throws SQLException {
|
||||
return ClickHouseStatementTracingWrapper.of(connectionInfo, "execute", sql, () -> delegate.execute(sql));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getResultSet() throws SQLException {
|
||||
return delegate.getResultSet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getUpdateCount() throws SQLException {
|
||||
return delegate.getUpdateCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getMoreResults() throws SQLException {
|
||||
return delegate.getMoreResults();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFetchDirection() throws SQLException {
|
||||
return delegate.getFetchDirection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFetchDirection(int direction) throws SQLException {
|
||||
delegate.setFetchDirection(direction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFetchSize() throws SQLException {
|
||||
return delegate.getFetchSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFetchSize(int rows) throws SQLException {
|
||||
delegate.setFetchSize(rows);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getResultSetConcurrency() throws SQLException {
|
||||
return delegate.getResultSetConcurrency();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getResultSetType() throws SQLException {
|
||||
return delegate.getResultSetType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBatch(String sql) throws SQLException {
|
||||
delegate.addBatch(sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearBatch() throws SQLException {
|
||||
delegate.clearBatch();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] executeBatch() throws SQLException {
|
||||
return ClickHouseStatementTracingWrapper.of(connectionInfo, "executeBatch", "", delegate::executeBatch);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection getConnection() throws SQLException {
|
||||
return delegate.getConnection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getMoreResults(int current) throws SQLException {
|
||||
return delegate.getMoreResults(current);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getGeneratedKeys() throws SQLException {
|
||||
return delegate.getGeneratedKeys();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
|
||||
return ClickHouseStatementTracingWrapper.of(connectionInfo, "executeUpdate", sql,
|
||||
() -> delegate.executeUpdate(sql, autoGeneratedKeys));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int executeUpdate(String sql, int[] columnIndexes) throws SQLException {
|
||||
return ClickHouseStatementTracingWrapper.of(connectionInfo, "executeUpdate", sql,
|
||||
() -> delegate.executeUpdate(sql, columnIndexes));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int executeUpdate(String sql, String[] columnNames) throws SQLException {
|
||||
return ClickHouseStatementTracingWrapper.of(connectionInfo, "executeUpdate", sql,
|
||||
() -> delegate.executeUpdate(sql, columnNames));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
|
||||
return ClickHouseStatementTracingWrapper.of(connectionInfo, "execute", sql,
|
||||
() -> delegate.execute(sql, autoGeneratedKeys));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(String sql, int[] columnIndexes) throws SQLException {
|
||||
return ClickHouseStatementTracingWrapper.of(connectionInfo, "execute", sql,
|
||||
() -> delegate.execute(sql, columnIndexes));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(String sql, String[] columnNames) throws SQLException {
|
||||
return ClickHouseStatementTracingWrapper.of(connectionInfo, "execute", sql,
|
||||
() -> delegate.execute(sql, columnNames));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getResultSetHoldability() throws SQLException {
|
||||
return delegate.getResultSetHoldability();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClosed() throws SQLException {
|
||||
return delegate.isClosed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPoolable() throws SQLException {
|
||||
return delegate.isPoolable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPoolable(boolean poolable) throws SQLException {
|
||||
delegate.setPoolable(poolable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeOnCompletion() throws SQLException {
|
||||
delegate.closeOnCompletion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCloseOnCompletion() throws SQLException {
|
||||
return delegate.isCloseOnCompletion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T unwrap(Class<T> iface) throws SQLException {
|
||||
return delegate.unwrap(iface);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWrapperFor(Class<?> iface) throws SQLException {
|
||||
return delegate.isWrapperFor(iface);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
* 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.skywalking.apm.plugin.jdbc.clickhouse.define;
|
||||
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
|
||||
|
||||
import net.bytebuddy.description.method.MethodDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
import net.bytebuddy.matcher.ElementMatchers;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
|
||||
import org.apache.skywalking.apm.plugin.jdbc.define.Constants;
|
||||
|
||||
/**
|
||||
* Intercept {@link ru.yandex.clickhouse.ClickHouseConnectionImpl} class.
|
||||
*/
|
||||
public class ConnectionInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
|
||||
|
||||
private final static String ENHANCE_CLASS = "ru.yandex.clickhouse.ClickHouseConnectionImpl";
|
||||
private final static String INIT_CONNECTION_METHOD_NAME = "initConnection";
|
||||
private final static String INIT_CONNECTION_METHOD_INTERCEPTOR = "org.apache.skywalking.apm.plugin.jdbc.clickhouse.InitConnectionMethodInterceptor";
|
||||
private final static String CREATE_CLICKHOUSE_STATEMENT_METHOD_NAME = "createClickHouseStatement";
|
||||
private final static String CREATE_CLICKHOUSE_STATEMENT_INTERCEPTOR = "org.apache.skywalking.apm.plugin.jdbc.clickhouse.ClickHouseStatementMethodInterceptor";
|
||||
|
||||
@Override
|
||||
protected ClassMatch enhanceClass() {
|
||||
return byName(ENHANCE_CLASS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
|
||||
return new ConstructorInterceptPoint[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
|
||||
return new InstanceMethodsInterceptPoint[] {
|
||||
new InstanceMethodsInterceptPoint() {
|
||||
@Override
|
||||
public ElementMatcher<MethodDescription> getMethodsMatcher() {
|
||||
return named(Constants.CREATE_STATEMENT_METHOD_NAME).or(
|
||||
named(CREATE_CLICKHOUSE_STATEMENT_METHOD_NAME));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethodsInterceptor() {
|
||||
return CREATE_CLICKHOUSE_STATEMENT_INTERCEPTOR;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverrideArgs() {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
new InstanceMethodsInterceptPoint() {
|
||||
@Override
|
||||
public ElementMatcher<MethodDescription> getMethodsMatcher() {
|
||||
return named(Constants.PREPARE_STATEMENT_METHOD_NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethodsInterceptor() {
|
||||
return Constants.PREPARE_STATEMENT_INTERCEPT_CLASS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverrideArgs() {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
new InstanceMethodsInterceptPoint() {
|
||||
@Override
|
||||
public ElementMatcher<MethodDescription> getMethodsMatcher() {
|
||||
return named(Constants.CLOSE_METHOD_NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethodsInterceptor() {
|
||||
return Constants.SERVICE_METHOD_INTERCEPT_CLASS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverrideArgs() {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
new InstanceMethodsInterceptPoint() {
|
||||
@Override
|
||||
public ElementMatcher<MethodDescription> getMethodsMatcher() {
|
||||
return named(INIT_CONNECTION_METHOD_NAME).and(ElementMatchers.takesArgument(0,
|
||||
named("ru.yandex.clickhouse.settings.ClickHouseProperties")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethodsInterceptor() {
|
||||
return INIT_CONNECTION_METHOD_INTERCEPTOR;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverrideArgs() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
# 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.
|
||||
|
||||
clickhouse-0.3.x=org.apache.skywalking.apm.plugin.jdbc.clickhouse.define.ConnectionInstrumentation
|
||||
|
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* 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.skywalking.apm.plugin.jdbc.clickhouse;
|
||||
|
||||
import static org.hamcrest.core.Is.is;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNotSame;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import java.util.List;
|
||||
import org.apache.skywalking.apm.agent.core.context.trace.AbstractTracingSpan;
|
||||
import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
|
||||
import org.apache.skywalking.apm.agent.core.context.trace.TraceSegment;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
|
||||
import org.apache.skywalking.apm.agent.test.helper.SegmentHelper;
|
||||
import org.apache.skywalking.apm.agent.test.tools.AgentServiceRule;
|
||||
import org.apache.skywalking.apm.agent.test.tools.SegmentStorage;
|
||||
import org.apache.skywalking.apm.agent.test.tools.SegmentStoragePoint;
|
||||
import org.apache.skywalking.apm.agent.test.tools.SpanAssert;
|
||||
import org.apache.skywalking.apm.agent.test.tools.TracingSegmentRunner;
|
||||
import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
|
||||
import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
import org.powermock.modules.junit4.PowerMockRunnerDelegate;
|
||||
import ru.yandex.clickhouse.ClickHouseStatementImpl;
|
||||
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PowerMockRunnerDelegate(TracingSegmentRunner.class)
|
||||
public class ClickHouseStatementMethodInterceptorTest {
|
||||
|
||||
private final static String SQL = "SELECT 1";
|
||||
private final EnhancedInstance enhancedInstance = new EnhancedInstance() {
|
||||
private Object value;
|
||||
|
||||
@Override
|
||||
public Object getSkyWalkingDynamicField() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSkyWalkingDynamicField(Object value) {
|
||||
this.value = value;
|
||||
}
|
||||
};
|
||||
private final ClickHouseStatementMethodInterceptor interceptor = new ClickHouseStatementMethodInterceptor();
|
||||
@Rule
|
||||
public AgentServiceRule serviceRule = new AgentServiceRule();
|
||||
@SegmentStoragePoint
|
||||
private SegmentStorage segmentStorage;
|
||||
@Mock
|
||||
private ConnectionInfo connectionInfo;
|
||||
@Mock
|
||||
private ClickHouseStatementImpl clickHouseStatement;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
// Mock connection info instance method
|
||||
when(connectionInfo.getComponent()).thenReturn(ComponentsDefine.CLICKHOUSE_JDBC_DRIVER);
|
||||
when(connectionInfo.getDatabaseName()).thenReturn("default");
|
||||
when(connectionInfo.getDatabasePeer()).thenReturn("127.0.0.1:8123");
|
||||
when(connectionInfo.getDBType()).thenReturn("ClickHouse");
|
||||
|
||||
// Mock clickhouse statement instance method
|
||||
when(clickHouseStatement.execute(SQL)).thenReturn(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithoutConnectionInfo() throws Throwable {
|
||||
final Object ret = interceptor.afterMethod(enhancedInstance, null, new Object[0], new Class[0],
|
||||
clickHouseStatement);
|
||||
|
||||
assertSame(clickHouseStatement, ret);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() throws Throwable {
|
||||
enhancedInstance.setSkyWalkingDynamicField(connectionInfo);
|
||||
final Object ret = interceptor.afterMethod(enhancedInstance, null, new Object[0], new Class[0],
|
||||
clickHouseStatement);
|
||||
|
||||
assertNotSame(clickHouseStatement, ret);
|
||||
assertSame(TracedClickHouseStatement.class, ret.getClass());
|
||||
TracedClickHouseStatement statement = (TracedClickHouseStatement) ret;
|
||||
final boolean result = statement.execute(SQL);
|
||||
assertTrue(result);
|
||||
|
||||
final List<TraceSegment> traceSegments = segmentStorage.getTraceSegments();
|
||||
assertThat(traceSegments.size(), is(1));
|
||||
final List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegments.get(0));
|
||||
assertNotNull(spans);
|
||||
assertThat(spans.size(), is(1));
|
||||
assertSpan(spans.get(0));
|
||||
}
|
||||
|
||||
private void assertSpan(final AbstractTracingSpan span) throws JsonProcessingException {
|
||||
SpanAssert.assertComponent(span, ComponentsDefine.CLICKHOUSE_JDBC_DRIVER);
|
||||
SpanAssert.assertLayer(span, SpanLayer.DB);
|
||||
SpanAssert.assertTagSize(span, 3);
|
||||
SpanAssert.assertTag(span, 0, "sql");
|
||||
SpanAssert.assertTag(span, 1, "default");
|
||||
SpanAssert.assertTag(span, 2, SQL);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* 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.skywalking.apm.plugin.jdbc.clickhouse;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
|
||||
import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
import ru.yandex.clickhouse.settings.ClickHouseProperties;
|
||||
|
||||
@RunWith(PowerMockRunner.class)
|
||||
public class InitConnectionMethodInterceptorTest {
|
||||
|
||||
private final EnhancedInstance enhancedInstance = new EnhancedInstance() {
|
||||
private Object value;
|
||||
|
||||
@Override
|
||||
public Object getSkyWalkingDynamicField() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSkyWalkingDynamicField(Object value) {
|
||||
this.value = value;
|
||||
}
|
||||
};
|
||||
private InitConnectionMethodInterceptor targetInterceptor;
|
||||
@Mock
|
||||
private ClickHouseProperties clickHouseProperties;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
targetInterceptor = new InitConnectionMethodInterceptor();
|
||||
when(clickHouseProperties.getHost()).thenReturn("127.0.0.1");
|
||||
when(clickHouseProperties.getPort()).thenReturn(8123);
|
||||
when(clickHouseProperties.getDatabase()).thenReturn("default");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() throws Throwable {
|
||||
targetInterceptor.beforeMethod(enhancedInstance, null, new Object[] {clickHouseProperties}, new Class[0], null);
|
||||
final ConnectionInfo connectionInfo = (ConnectionInfo) enhancedInstance.getSkyWalkingDynamicField();
|
||||
assertNotNull(connectionInfo);
|
||||
assertEquals("ClickHouse-jdbc-driver", connectionInfo.getComponent().getName());
|
||||
assertEquals("127.0.0.1:8123", connectionInfo.getDatabasePeer());
|
||||
assertEquals("default", connectionInfo.getDatabaseName());
|
||||
assertEquals("ClickHouse", connectionInfo.getDBType());
|
||||
}
|
||||
}
|
||||
|
|
@ -110,6 +110,7 @@
|
|||
<module>druid-1.x-plugin</module>
|
||||
<module>hikaricp-3.x-4.x-plugin</module>
|
||||
<module>httpclient-5.x-plugin</module>
|
||||
<module>clickhouse-0.3.x-plugin</module>
|
||||
</modules>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
|
|
|
|||
|
|
@ -124,3 +124,4 @@
|
|||
- jsonrpc4j
|
||||
- spring-cloud-gateway-3.x
|
||||
- neo4j-4.x
|
||||
- clickhouse-0.3.x
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ metrics based on the tracing data.
|
|||
* [InfluxDB](https://github.com/influxdata/influxdb-java) 2.5 -> 2.17
|
||||
* [Mssql-Jtds](https://github.com/milesibastos/jTDS) 1.x
|
||||
* [Mssql-jdbc](https://github.com/microsoft/mssql-jdbc) 6.x -> 8.x
|
||||
* [ClickHouse-jdbc](https://github.com/ClickHouse/clickhouse-jdbc) 0.3.x
|
||||
* RPC Frameworks
|
||||
* [Dubbo](https://github.com/alibaba/dubbo) 2.5.4 -> 2.6.0
|
||||
* [Dubbox](https://github.com/dangdangdotcom/dubbox) 2.8.4
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# 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.
|
||||
|
||||
home="$(
|
||||
cd "$(dirname $0)"
|
||||
pwd
|
||||
)"
|
||||
|
||||
java -jar ${agent_opts} "-Dskywalking.plugin.neo4j.trace_cypher_parameters=true" ${home}/../libs/clickhouse-0.3.x-scenario.jar &
|
||||
|
|
@ -0,0 +1,182 @@
|
|||
# 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.
|
||||
segmentItems:
|
||||
- serviceName: clickhouse-0.3.x-scenario
|
||||
segmentSize: ge 2
|
||||
segments:
|
||||
- segmentId: not null
|
||||
spans:
|
||||
- operationName: HEAD:/clickhouse-scenario/case/healthCheck
|
||||
operationId: 0
|
||||
parentSpanId: -1
|
||||
spanId: 0
|
||||
spanLayer: Http
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 1
|
||||
isError: false
|
||||
spanType: Entry
|
||||
peer: ''
|
||||
skipAnalysis: false
|
||||
tags:
|
||||
- {key: url, value: 'http://localhost:8080/clickhouse-scenario/case/healthCheck'}
|
||||
- {key: http.method, value: HEAD}
|
||||
- segmentId: not null
|
||||
spans:
|
||||
- operationName: ClickHouse/JDBI/Statement/executeQuery
|
||||
operationId: 0
|
||||
parentSpanId: 0
|
||||
spanId: 1
|
||||
spanLayer: Database
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 119
|
||||
isError: false
|
||||
spanType: Exit
|
||||
peer: not null
|
||||
skipAnalysis: false
|
||||
tags:
|
||||
- {key: db.type, value: sql}
|
||||
- {key: db.instance, value: system}
|
||||
- {key: db.statement, value: 'select timezone(), version()'}
|
||||
- operationName: ClickHouse/JDBI/Statement/executeQuery
|
||||
operationId: 0
|
||||
parentSpanId: 0
|
||||
spanId: 2
|
||||
spanLayer: Database
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 119
|
||||
isError: false
|
||||
spanType: Exit
|
||||
peer: not null
|
||||
skipAnalysis: false
|
||||
tags:
|
||||
- {key: db.type, value: sql}
|
||||
- {key: db.instance, value: system}
|
||||
- {key: db.statement, value: SELECT * FROM clusters}
|
||||
- operationName: ClickHouse/JDBI/Statement/execute
|
||||
operationId: 0
|
||||
parentSpanId: 0
|
||||
spanId: 3
|
||||
spanLayer: Database
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 119
|
||||
isError: false
|
||||
spanType: Exit
|
||||
peer: not null
|
||||
skipAnalysis: false
|
||||
tags:
|
||||
- {key: db.type, value: sql}
|
||||
- {key: db.instance, value: system}
|
||||
- {key: db.statement, value: SELECT 1}
|
||||
- operationName: ClickHouse/JDBI/Connection/close
|
||||
operationId: 0
|
||||
parentSpanId: 0
|
||||
spanId: 4
|
||||
spanLayer: Database
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 119
|
||||
isError: false
|
||||
spanType: Exit
|
||||
peer: not null
|
||||
skipAnalysis: false
|
||||
tags:
|
||||
- {key: db.type, value: sql}
|
||||
- {key: db.instance, value: system}
|
||||
- {key: db.statement, value: ''}
|
||||
- operationName: ClickHouse/JDBI/Statement/executeQuery
|
||||
operationId: 0
|
||||
parentSpanId: 0
|
||||
spanId: 5
|
||||
spanLayer: Database
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 119
|
||||
isError: false
|
||||
spanType: Exit
|
||||
peer: not null
|
||||
skipAnalysis: false
|
||||
tags:
|
||||
- {key: db.type, value: sql}
|
||||
- {key: db.instance, value: system}
|
||||
- {key: db.statement, value: 'select timezone(), version()'}
|
||||
- operationName: ClickHouse/JDBI/PreparedStatement/executeQuery
|
||||
operationId: 0
|
||||
parentSpanId: 0
|
||||
spanId: 6
|
||||
spanLayer: Database
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 119
|
||||
isError: false
|
||||
spanType: Exit
|
||||
peer: not null
|
||||
skipAnalysis: false
|
||||
tags:
|
||||
- {key: db.type, value: sql}
|
||||
- {key: db.instance, value: system}
|
||||
- {key: db.statement, value: SELECT * FROM clusters}
|
||||
- operationName: ClickHouse/JDBI/Statement/execute
|
||||
operationId: 0
|
||||
parentSpanId: 0
|
||||
spanId: 7
|
||||
spanLayer: Database
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 119
|
||||
isError: false
|
||||
spanType: Exit
|
||||
peer: not null
|
||||
skipAnalysis: false
|
||||
tags:
|
||||
- {key: db.type, value: sql}
|
||||
- {key: db.instance, value: system}
|
||||
- {key: db.statement, value: SELECT 1}
|
||||
- operationName: ClickHouse/JDBI/Connection/close
|
||||
operationId: 0
|
||||
parentSpanId: 0
|
||||
spanId: 8
|
||||
spanLayer: Database
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 119
|
||||
isError: false
|
||||
spanType: Exit
|
||||
peer: not null
|
||||
skipAnalysis: false
|
||||
tags:
|
||||
- {key: db.type, value: sql}
|
||||
- {key: db.instance, value: system}
|
||||
- {key: db.statement, value: ''}
|
||||
- operationName: GET:/clickhouse-scenario/case/clickhouse-scenario
|
||||
operationId: 0
|
||||
parentSpanId: -1
|
||||
spanId: 0
|
||||
spanLayer: Http
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 1
|
||||
isError: false
|
||||
spanType: Entry
|
||||
peer: ''
|
||||
skipAnalysis: false
|
||||
tags:
|
||||
- {key: url, value: 'http://localhost:8080/clickhouse-scenario/case/clickhouse-scenario'}
|
||||
- {key: http.method, value: GET}
|
||||
meterItems: []
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
# 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.
|
||||
|
||||
type: jvm
|
||||
entryService: http://localhost:8080/clickhouse-scenario/case/clickhouse-scenario
|
||||
healthCheck: http://localhost:8080/clickhouse-scenario/case/healthCheck
|
||||
startScript: ./bin/startup.sh
|
||||
environment:
|
||||
depends_on:
|
||||
- clickhouse-server
|
||||
dependencies:
|
||||
clickhouse-server:
|
||||
image: yandex/clickhouse-server:21.8.8.29
|
||||
hostname: clickhouse-server
|
||||
expose:
|
||||
- 8123
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ 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.
|
||||
~
|
||||
-->
|
||||
<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">
|
||||
|
||||
<groupId>org.apache.skywalking.apm.testcase</groupId>
|
||||
<artifactId>clickhouse-0.3.x-scenario</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<compiler.version>1.8</compiler.version>
|
||||
<test.framework.version>0.3.1-patch</test.framework.version>
|
||||
<spring-boot-version>2.5.1</spring-boot-version>
|
||||
</properties>
|
||||
|
||||
<name>skywalking-clickhouse-0.3.x-scenario</name>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-dependencies</artifactId>
|
||||
<version>${spring-boot-version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-logging</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-log4j2</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>ru.yandex.clickhouse</groupId>
|
||||
<artifactId>clickhouse-jdbc</artifactId>
|
||||
<version>${test.framework.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>clickhouse-0.3.x-scenario</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>${compiler.version}</source>
|
||||
<target>${compiler.version}</target>
|
||||
<encoding>${project.build.sourceEncoding}</encoding>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>assemble</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<descriptors>
|
||||
<descriptor>src/main/assembly/assembly.xml</descriptor>
|
||||
</descriptors>
|
||||
<outputDirectory>./target/</outputDirectory>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ 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.
|
||||
~
|
||||
-->
|
||||
<assembly
|
||||
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
|
||||
<formats>
|
||||
<format>zip</format>
|
||||
</formats>
|
||||
|
||||
<fileSets>
|
||||
<fileSet>
|
||||
<directory>./bin</directory>
|
||||
<fileMode>0775</fileMode>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
|
||||
<files>
|
||||
<file>
|
||||
<source>${project.build.directory}/clickhouse-0.3.x-scenario.jar</source>
|
||||
<outputDirectory>./libs</outputDirectory>
|
||||
<fileMode>0775</fileMode>
|
||||
</file>
|
||||
</files>
|
||||
</assembly>
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* 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.skywalking.apm.testcase.neo4j;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import ru.yandex.clickhouse.ClickHouseDataSource;
|
||||
import ru.yandex.clickhouse.settings.ClickHouseProperties;
|
||||
|
||||
@SpringBootApplication
|
||||
public class Application {
|
||||
|
||||
@Value("${clickhouse.jdbc.url:jdbc:clickhouse://clickhouse-server:8123/system}")
|
||||
private String clickhouseJdbcUrl;
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
SpringApplication.run(Application.class, args);
|
||||
} catch (Exception e) {
|
||||
// Never do this
|
||||
}
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ClickHouseDataSource dataSource() {
|
||||
ClickHouseProperties properties = new ClickHouseProperties();
|
||||
properties.setClientName("Agent #1");
|
||||
properties.setSessionId("default-session-id");
|
||||
|
||||
return new ClickHouseDataSource(clickhouseJdbcUrl, properties);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* 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.skywalking.apm.testcase.neo4j.controller;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import javax.annotation.Resource;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import ru.yandex.clickhouse.ClickHouseConnection;
|
||||
import ru.yandex.clickhouse.ClickHouseDataSource;
|
||||
import ru.yandex.clickhouse.ClickHouseStatement;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/case")
|
||||
public class CaseController {
|
||||
|
||||
private static final String SUCCESS = "Success";
|
||||
private static final String SQL = "SELECT * FROM clusters";
|
||||
@Resource
|
||||
private ClickHouseDataSource dataSource;
|
||||
|
||||
@RequestMapping("/clickhouse-scenario")
|
||||
@ResponseBody
|
||||
public String testcase() throws Exception {
|
||||
try (ClickHouseConnection conn = dataSource.getConnection();
|
||||
ClickHouseStatement stmt = conn.createStatement();
|
||||
ResultSet ignored = stmt.executeQuery(SQL)) {
|
||||
conn.isValid(3);
|
||||
}
|
||||
|
||||
try (final ClickHouseConnection connection = dataSource.getConnection();
|
||||
final PreparedStatement preparedStatement = connection.prepareStatement(SQL);
|
||||
final ResultSet ignored = preparedStatement.executeQuery()) {
|
||||
connection.isValid(3);
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@RequestMapping("/healthCheck")
|
||||
@ResponseBody
|
||||
public String healthCheck() throws Exception {
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
#
|
||||
# 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.
|
||||
#
|
||||
#
|
||||
server:
|
||||
port: 8080
|
||||
servlet:
|
||||
context-path: /clickhouse-scenario
|
||||
logging:
|
||||
config: classpath:log4j2.xml
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ 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.
|
||||
~
|
||||
-->
|
||||
<Configuration status="WARN">
|
||||
<Appenders>
|
||||
<Console name="Console">
|
||||
<PatternLayout charset="UTF-8"
|
||||
pattern="[%d{yyyy-MM-dd HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
|
||||
</Console>
|
||||
</Appenders>
|
||||
<Loggers>
|
||||
<Root level="INFO">
|
||||
<AppenderRef ref="Console"/>
|
||||
</Root>
|
||||
</Loggers>
|
||||
</Configuration>
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
# 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.
|
||||
|
||||
0.3.0
|
||||
0.3.1
|
||||
Loading…
Reference in New Issue