Unverified Commit a3241f0a authored by 吴晟's avatar 吴晟 Committed by GitHub
Browse files

Support op group name in agent config core. (#3299)

* Support op group name in agent config core.

* Provide core API for operation name grouping, rest template plugin update, and doc update.

* Fix doc

* Fix test case.

* Fix missing changes.

* add shuyun to powered-by.md (#3341)

* add shuyun to powered-by.md

* update powered-by.md

* Remove static method.
parent 1cc4a517
Loading
Loading
Loading
Loading
+35 −17
Original line number Diff line number Diff line
@@ -23,12 +23,12 @@ import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.logging.Logger;

/**
 * Init a class's static fields by a {@link Properties},
 * including static fields and static inner classes.
 * Init a class's static fields by a {@link Properties}, including static fields and static inner classes.
 * <p>
 * Created by wusheng on 2017/1/9.
 */
@@ -44,6 +44,23 @@ public class ConfigInitializer {
        for (Field field : recentConfigType.getFields()) {
            if (Modifier.isPublic(field.getModifiers()) && Modifier.isStatic(field.getModifiers())) {
                String configKey = (parentDesc + "." + field.getName()).toLowerCase();
                /**
                 * Map config format is, config_key[map_key]=map_value
                 * Such as plugin.opgroup.resttemplate.rule[abc]=/url/path
                 */
                if (field.getType().equals(Map.class)) {
                    Map map = (Map)field.get(null);
                    for (Object key : properties.keySet()) {
                        String stringKey = key.toString();
                        if (stringKey.startsWith(configKey + "[") && stringKey.endsWith("]")) {
                            String itemKey = stringKey.substring(configKey.length() + 1, stringKey.length() - 1);
                            map.put(itemKey, properties.getProperty(stringKey));
                        }
                    }
                } else {
                    /**
                     * Others typical field type
                     */
                    String value = properties.getProperty(configKey);
                    if (value != null) {
                        Class<?> type = field.getType();
@@ -62,6 +79,7 @@ public class ConfigInitializer {
                    }
                }
            }
        }
        for (Class<?> innerConfiguration : recentConfigType.getClasses()) {
            parentDesc.append(innerConfiguration.getSimpleName());
            initNextLevel(properties, innerConfiguration, parentDesc);
+40 −34
Original line number Diff line number Diff line
@@ -19,14 +19,13 @@

package org.apache.skywalking.apm.agent.core.conf;

import java.util.HashMap;
import java.util.Map;
import org.apache.skywalking.apm.agent.core.context.trace.TraceSegment;
import org.apache.skywalking.apm.agent.core.logging.core.LogLevel;
import org.apache.skywalking.apm.agent.core.logging.core.LogOutput;
import org.apache.skywalking.apm.agent.core.logging.core.WriterFactory;

import java.util.HashMap;
import java.util.Map;

/**
 * This is the core config in sniffer agent.
 *
@@ -41,14 +40,14 @@ public class Config {
        public static String NAMESPACE = "";

        /**
         * Service name is showed in skywalking-ui. Suggestion: set a unique name for each service,
         * service instance nodes share the same code
         * Service name is showed in skywalking-ui. Suggestion: set a unique name for each service, service instance
         * nodes share the same code
         */
        public static String SERVICE_NAME = "";

        /**
         * Authentication active is based on backend setting, see application.yml for more details.
         * For most scenarios, this needs backend extensions, only basic match auth provided in default implementation.
         * Authentication active is based on backend setting, see application.yml for more details. For most scenarios,
         * this needs backend extensions, only basic match auth provided in default implementation.
         */
        public static String AUTHENTICATION = "";

@@ -70,8 +69,8 @@ public class Config {
        public static int SPAN_LIMIT_PER_SEGMENT = 300;

        /**
         * If true, skywalking agent will save all instrumented classes files in `/debugging` folder.
         * Skywalking team may ask for these files in order to resolve compatible problem.
         * If true, skywalking agent will save all instrumented classes files in `/debugging` folder. Skywalking team
         * may ask for these files in order to resolve compatible problem.
         */
        public static boolean IS_OPEN_DEBUGGING_CLASS = false;

@@ -96,16 +95,14 @@ public class Config {
        public static int CAUSE_EXCEPTION_DEPTH = 5;

        /**
         * How long should the agent wait (in minute)
         * before re-registering to the OAP server
         * after receiving reset command
         * How long should the agent wait (in minute) before re-registering to the OAP server after receiving reset
         * command
         */
        public static int COOL_DOWN_THRESHOLD = 10;

        /**
         * Force reconnection period of grpc, based on grpc_channel_check_interval.
         * If count of check grpc channel status more than this number.
         * The channel check will call channel.getState(true) to requestConnection.
         * Force reconnection period of grpc, based on grpc_channel_check_interval. If count of check grpc channel
         * status more than this number. The channel check will call channel.getState(true) to requestConnection.
         */
        public static long FORCE_RECONNECTION_PERIOD = 1;
    }
@@ -177,19 +174,13 @@ public class Config {
        public static LogOutput OUTPUT = LogOutput.FILE;

        /**
         * The log patten. Default is "%level %timestamp %thread %class : %msg %throwable".
         * Each conversion specifiers starts with a percent sign '%' and fis followed by conversion word.
         * There are some default conversion specifiers:
         * %thread = ThreadName
         * %level = LogLevel  {@link LogLevel}
         * %timestamp = The now() who format is 'yyyy-MM-dd HH:mm:ss:SSS'
         * %class = SimpleName of TargetClass
         * %msg = Message of user input
         * %throwable = Throwable of user input
         * %agent_name = ServiceName of Agent {@link Agent#SERVICE_NAME}
         * The log patten. Default is "%level %timestamp %thread %class : %msg %throwable". Each conversion specifiers
         * starts with a percent sign '%' and fis followed by conversion word. There are some default conversion
         * specifiers: %thread = ThreadName %level = LogLevel  {@link LogLevel} %timestamp = The now() who format is
         * 'yyyy-MM-dd HH:mm:ss:SSS' %class = SimpleName of TargetClass %msg = Message of user input %throwable =
         * Throwable of user input %agent_name = ServiceName of Agent {@link Agent#SERVICE_NAME}
         *
         * @see org.apache.skywalking.apm.agent.core.logging.core.PatternLogger#DEFAULT_CONVERTER_MAP
         *
         */
        public static String PATTERN = "%level %timestamp %thread %class : %msg %throwable";
    }
@@ -203,7 +194,8 @@ public class Config {

        public static class MongoDB {
            /**
             * If true, trace all the parameters in MongoDB access, default is false. Only trace the operation, not include parameters.
             * If true, trace all the parameters in MongoDB access, default is false. Only trace the operation, not
             * include parameters.
             */
            public static boolean TRACE_PARAM = false;
        }
@@ -230,27 +222,29 @@ public class Config {

        public static class SpringMVC {
            /**
             * If true, the fully qualified method name will be used as the endpoint name instead of the request URL, default is false.
             * If true, the fully qualified method name will be used as the endpoint name instead of the request URL,
             * default is false.
             */
            public static boolean USE_QUALIFIED_NAME_AS_ENDPOINT_NAME = false;
        }

        public static class Toolkit {
            /**
             * If true, the fully qualified method name will be used as the operation name instead of the given operation name, default is false.
             * If true, the fully qualified method name will be used as the operation name instead of the given
             * operation name, default is false.
             */
            public static boolean USE_QUALIFIED_NAME_AS_OPERATION_NAME = false;
        }

        public static class MySQL {
            /**
             * If set to true, the parameters of the sql (typically {@link java.sql.PreparedStatement})
             * would be collected.
             * If set to true, the parameters of the sql (typically {@link java.sql.PreparedStatement}) would be
             * collected.
             */
            public static boolean TRACE_SQL_PARAMETERS = false;
            /**
             * For the sake of performance, SkyWalking won't save the entire parameters string into the tag,
             * but only the first {@code SQL_PARAMETERS_MAX_LENGTH} characters.
             * For the sake of performance, SkyWalking won't save the entire parameters string into the tag, but only
             * the first {@code SQL_PARAMETERS_MAX_LENGTH} characters.
             *
             * Set a negative number to save the complete parameter string to the tag.
             */
@@ -259,7 +253,8 @@ public class Config {

        public static class SolrJ {
            /**
             * If true, trace all the query parameters(include deleteByIds and deleteByQuery) in Solr query request, default is false.
             * If true, trace all the query parameters(include deleteByIds and deleteByQuery) in Solr query request,
             * default is false.
             */
            public static boolean TRACE_STATEMENT = false;

@@ -269,5 +264,16 @@ public class Config {
            public static boolean TRACE_OPS_PARAMS = false;
        }

        /**
         * Operation name group rules
         */
        public static class OPGroup {
            /**
             * Rules for RestTemplate plugin
             */
            public static class RestTemplate implements OPGroupDefinition {
                public static Map<String, String> RULE = new HashMap<String, String>();
            }
        }
    }
}
+25 −0
Original line number Diff line number Diff line
/*
 * 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.agent.core.conf;

/**
 * @author wusheng
 */
public interface OPGroupDefinition {
}
+90 −0
Original line number Diff line number Diff line
/*
 * 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.agent.core.context;

import java.lang.reflect.Field;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.skywalking.apm.agent.core.boot.BootService;
import org.apache.skywalking.apm.agent.core.boot.DefaultImplementor;
import org.apache.skywalking.apm.agent.core.conf.Config;
import org.apache.skywalking.apm.agent.core.conf.OPGroupDefinition;
import org.apache.skywalking.apm.util.StringFormatGroup;

/**
 * Support operation name format by config. Every plugin could declare its own rule to avoid performance concerns.
 *
 * Right now, the rule is REGEX based, it definitely has much space to optimize, because basically, only `*` is required
 * to be supported.
 *
 * @author wusheng
 */
@DefaultImplementor
public class OperationNameFormatService implements BootService {
    private static final Map<Class, StringFormatGroup> RULES = new ConcurrentHashMap<Class, StringFormatGroup>();

    @Override public void prepare() throws Throwable {
        for (Class<?> ruleName : Config.Plugin.OPGroup.class.getClasses()) {
            if (!OPGroupDefinition.class.isAssignableFrom(ruleName)) {
                continue;
            }
            StringFormatGroup formatGroup = RULES.get(ruleName);
            if (formatGroup == null) {
                formatGroup = new StringFormatGroup();
                RULES.put(ruleName, formatGroup);
            }
            for (Field ruleNameField : ruleName.getFields()) {
                if (ruleNameField.getType().equals(Map.class)) {
                    Map<String, String> rule = (Map<String, String>)ruleNameField.get(null);
                    for (Map.Entry<String, String> entry : rule.entrySet()) {
                        formatGroup.addRule(entry.getKey(), entry.getValue());
                    }
                }
            }
        }
    }

    @Override public void boot() throws Throwable {

    }

    @Override public void onComplete() throws Throwable {

    }

    @Override public void shutdown() throws Throwable {

    }

    /**
     * Format the operation name based on group rules
     *
     * @param definition in the Config
     * @param opName represents the operation name literal string
     * @return format string if rule matched or the given opName
     */
    public String formatOperationName(Class<? extends OPGroupDefinition> definition, String opName) {
        StringFormatGroup formatGroup = RULES.get(definition);
        if (formatGroup == null) {
            return opName;
        } else {
            return formatGroup.format(opName).getName();
        }
    }
}
+1 −0
Original line number Diff line number Diff line
@@ -25,3 +25,4 @@ org.apache.skywalking.apm.agent.core.remote.ServiceAndEndpointRegisterClient
org.apache.skywalking.apm.agent.core.context.ContextManagerExtendService
org.apache.skywalking.apm.agent.core.commands.CommandService
org.apache.skywalking.apm.agent.core.commands.CommandExecutorService
org.apache.skywalking.apm.agent.core.context.OperationNameFormatService
Loading