| /* |
| * 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.oap.server.core.source; |
| |
| import java.lang.annotation.Annotation; |
| import java.lang.reflect.Field; |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| import lombok.Setter; |
| import org.apache.skywalking.oap.server.core.UnexpectedException; |
| import org.apache.skywalking.oap.server.core.annotation.AnnotationListener; |
| |
| public class DefaultScopeDefine { |
| private static final Map<String, Integer> NAME_2_ID = new HashMap<>(); |
| private static final Map<Integer, String> ID_2_NAME = new HashMap<>(); |
| private static final Map<String, List<ScopeDefaultColumn>> SCOPE_COLUMNS = new HashMap<>(); |
| |
| /** |
| * All metrics IDs in [0, 10,000) are reserved in Apache SkyWalking. |
| * <p> |
| * If you want to extend the scope, recommend to start with 10,000. |
| */ |
| |
| /** |
| * @since 9.0.0 |
| */ |
| public static final int UNKNOWN = 0; |
| /** |
| * @since Deprecated from 9.0.0 |
| */ |
| @Deprecated |
| public static final int ALL = 0; |
| public static final int SERVICE = 1; |
| public static final int SERVICE_INSTANCE = 2; |
| public static final int ENDPOINT = 3; |
| public static final int SERVICE_RELATION = 4; |
| public static final int SERVICE_INSTANCE_RELATION = 5; |
| public static final int ENDPOINT_RELATION = 6; |
| public static final int SERVICE_INSTANCE_JVM_CPU = 8; |
| public static final int SERVICE_INSTANCE_JVM_MEMORY = 9; |
| public static final int SERVICE_INSTANCE_JVM_MEMORY_POOL = 10; |
| public static final int SERVICE_INSTANCE_JVM_GC = 11; |
| public static final int SEGMENT = 12; |
| public static final int ALARM = 13; |
| public static final int DATABASE_ACCESS = 17; |
| public static final int DATABASE_SLOW_STATEMENT = 18; |
| public static final int SERVICE_INSTANCE_CLR_CPU = 19; |
| public static final int SERVICE_INSTANCE_CLR_GC = 20; |
| public static final int SERVICE_INSTANCE_CLR_THREAD = 21; |
| public static final int ENVOY_INSTANCE_METRIC = 22; |
| public static final int ZIPKIN_SPAN = 23; |
| @Deprecated |
| public static final int JAEGER_SPAN = 24; |
| @Deprecated |
| public static final int HTTP_ACCESS_LOG = 25; |
| public static final int PROFILE_TASK = 26; |
| public static final int PROFILE_TASK_LOG = 27; |
| public static final int PROFILE_TASK_SEGMENT_SNAPSHOT = 28; |
| public static final int SERVICE_META = 29; |
| public static final int SERVICE_INSTANCE_UPDATE = 30; |
| public static final int NETWORK_ADDRESS_ALIAS = 31; |
| public static final int UI_TEMPLATE = 32; |
| public static final int SERVICE_INSTANCE_JVM_THREAD = 33; |
| |
| // browser |
| public static final int BROWSER_ERROR_LOG = 34; |
| public static final int BROWSER_APP_PERF = 35; |
| public static final int BROWSER_APP_PAGE_PERF = 36; |
| public static final int BROWSER_APP_SINGLE_VERSION_PERF = 37; |
| public static final int BROWSER_APP_TRAFFIC = 38; |
| public static final int BROWSER_APP_SINGLE_VERSION_TRAFFIC = 39; |
| public static final int BROWSER_APP_PAGE_TRAFFIC = 40; |
| |
| public static final int LOG = 41; |
| public static final int ENDPOINT_META = 42; |
| |
| public static final int EVENT = 43; |
| |
| public static final int SERVICE_INSTANCE_JVM_CLASS = 44; |
| |
| public static final int PROCESS = 45; |
| public static final int EBPF_PROFILING_TASK = 46; |
| public static final int EBPF_PROFILING_SCHEDULE = 47; |
| public static final int EBPF_PROFILING_DATA = 48; |
| public static final int SERVICE_LABEL = 49; |
| public static final int TAG_AUTOCOMPLETE = 50; |
| public static final int ZIPKIN_SERVICE = 51; |
| public static final int ZIPKIN_SERVICE_SPAN = 52; |
| public static final int ZIPKIN_SERVICE_RELATION = 53; |
| public static final int PROCESS_RELATION = 54; |
| |
| /** |
| * Catalog of scope, the metrics processor could use this to group all generated metrics by oal rt. |
| */ |
| public static final String SERVICE_CATALOG_NAME = "SERVICE"; |
| public static final String SERVICE_INSTANCE_CATALOG_NAME = "SERVICE_INSTANCE"; |
| public static final String ENDPOINT_CATALOG_NAME = "ENDPOINT"; |
| public static final String SERVICE_RELATION_CATALOG_NAME = "SERVICE_RELATION"; |
| public static final String SERVICE_INSTANCE_RELATION_CATALOG_NAME = "SERVICE_INSTANCE_RELATION"; |
| public static final String ENDPOINT_RELATION_CATALOG_NAME = "ENDPOINT_RELATION"; |
| public static final String PROCESS_CATALOG_NAME = "PROCESS"; |
| public static final String PROCESS_RELATION_CATALOG_NAME = "PROCESS_RELATION"; |
| |
| private static final Map<Integer, Boolean> SERVICE_CATALOG = new HashMap<>(); |
| private static final Map<Integer, Boolean> SERVICE_INSTANCE_CATALOG = new HashMap<>(); |
| private static final Map<Integer, Boolean> ENDPOINT_CATALOG = new HashMap<>(); |
| private static final Map<Integer, Boolean> SERVICE_RELATION_CATALOG = new HashMap<>(); |
| private static final Map<Integer, Boolean> SERVICE_INSTANCE_RELATION_CATALOG = new HashMap<>(); |
| private static final Map<Integer, Boolean> ENDPOINT_RELATION_CATALOG = new HashMap<>(); |
| private static final Map<Integer, Boolean> PROCESS_CATALOG = new HashMap<>(); |
| private static final Map<Integer, Boolean> PROCESS_RELATION_CATALOG = new HashMap<>(); |
| |
| @Setter |
| private static boolean ACTIVE_EXTRA_MODEL_COLUMNS = false; |
| |
| public static void activeExtraModelColumns() { |
| ACTIVE_EXTRA_MODEL_COLUMNS = true; |
| } |
| |
| /** |
| * Annotation scan listener |
| */ |
| public static class Listener implements AnnotationListener { |
| @Override |
| public Class<? extends Annotation> annotation() { |
| return ScopeDeclaration.class; |
| } |
| |
| @Override |
| public void notify(Class originalClass) { |
| ScopeDeclaration declaration = (ScopeDeclaration) originalClass.getAnnotation(ScopeDeclaration.class); |
| if (declaration != null) { |
| addNewScope(declaration, originalClass); |
| } |
| } |
| } |
| |
| /** |
| * Add a new scope based on the scan result |
| * |
| * @param declaration includes the definition. |
| * @param originalClass represents the class having the {@link ScopeDeclaration} annotation |
| */ |
| private static final void addNewScope(ScopeDeclaration declaration, Class originalClass) { |
| int id = declaration.id(); |
| if (ID_2_NAME.containsKey(id)) { |
| throw new UnexpectedException( |
| "ScopeDeclaration id=" + id + " at " + originalClass.getName() + " has conflict with another named " + ID_2_NAME |
| .get(id)); |
| } |
| if (id < 0) { |
| throw new UnexpectedException( |
| "ScopeDeclaration id=" + id + " at " + originalClass.getName() + " is negative. "); |
| } |
| String name = declaration.name(); |
| if (NAME_2_ID.containsKey(name)) { |
| throw new UnexpectedException( |
| "ScopeDeclaration fieldName=" + name + " at " + originalClass.getName() + " has conflict with another id= " + NAME_2_ID |
| .get(name)); |
| } |
| |
| ID_2_NAME.put(id, name); |
| NAME_2_ID.put(name, id); |
| |
| List<ScopeDefaultColumn> scopeDefaultColumns = new ArrayList<>(); |
| |
| ScopeDefaultColumn.VirtualColumnDefinition virtualColumn = (ScopeDefaultColumn.VirtualColumnDefinition) originalClass |
| .getAnnotation(ScopeDefaultColumn.VirtualColumnDefinition.class); |
| if (virtualColumn != null) { |
| scopeDefaultColumns.add( |
| new ScopeDefaultColumn(virtualColumn.fieldName(), virtualColumn.columnName(), virtualColumn |
| .type(), virtualColumn.isID(), virtualColumn.length())); |
| } |
| Field[] scopeClassField = originalClass.getDeclaredFields(); |
| if (scopeClassField != null) { |
| for (Field field : scopeClassField) { |
| ScopeDefaultColumn.DefinedByField definedByField = field.getAnnotation( |
| ScopeDefaultColumn.DefinedByField.class); |
| if (definedByField != null) { |
| if (!definedByField.requireDynamicActive() || ACTIVE_EXTRA_MODEL_COLUMNS) { |
| scopeDefaultColumns.add( |
| new ScopeDefaultColumn( |
| field.getName(), definedByField.columnName(), field.getType(), false, |
| definedByField.length() |
| )); |
| } |
| } |
| } |
| } |
| |
| SCOPE_COLUMNS.put(name, scopeDefaultColumns); |
| |
| String catalogName = declaration.catalog(); |
| switch (catalogName) { |
| case SERVICE_CATALOG_NAME: |
| SERVICE_CATALOG.put(id, Boolean.TRUE); |
| break; |
| case SERVICE_INSTANCE_CATALOG_NAME: |
| SERVICE_INSTANCE_CATALOG.put(id, Boolean.TRUE); |
| break; |
| case ENDPOINT_CATALOG_NAME: |
| ENDPOINT_CATALOG.put(id, Boolean.TRUE); |
| break; |
| case SERVICE_RELATION_CATALOG_NAME: |
| SERVICE_RELATION_CATALOG.put(id, Boolean.TRUE); |
| break; |
| case SERVICE_INSTANCE_RELATION_CATALOG_NAME: |
| SERVICE_INSTANCE_RELATION_CATALOG.put(id, Boolean.TRUE); |
| break; |
| case ENDPOINT_RELATION_CATALOG_NAME: |
| ENDPOINT_RELATION_CATALOG.put(id, Boolean.TRUE); |
| break; |
| case PROCESS_CATALOG_NAME: |
| PROCESS_CATALOG.put(id, Boolean.TRUE); |
| break; |
| case PROCESS_RELATION_CATALOG_NAME: |
| PROCESS_RELATION_CATALOG.put(id, Boolean.TRUE); |
| break; |
| } |
| } |
| |
| /** |
| * Fetch the name from given id |
| * |
| * @param id represents an existing scope id. |
| * @return scope name. |
| */ |
| public static String nameOf(int id) { |
| String name = ID_2_NAME.get(id); |
| if (name == null) { |
| throw new UnexpectedException("ScopeDefine id = " + id + " not found."); |
| } |
| return name; |
| } |
| |
| /** |
| * Fetch the id of given name |
| * |
| * @param name represents an existing scope name |
| * @return scope id |
| */ |
| public static int valueOf(String name) { |
| Integer id = NAME_2_ID.get(name); |
| if (id == null) { |
| throw new UnexpectedException("ScopeDefine fieldName = " + name + " not found."); |
| } |
| return id; |
| } |
| |
| /** |
| * Reset all existing scope definitions. For test only. |
| */ |
| public static void reset() { |
| NAME_2_ID.clear(); |
| ID_2_NAME.clear(); |
| SCOPE_COLUMNS.clear(); |
| } |
| |
| /** |
| * Check whether the given scope ID belongs service catalog |
| * |
| * @param scopeId represents an existing scope id. |
| * @return true is current scope set {@link ScopeDeclaration#catalog()} == {@link #SERVICE_CATALOG_NAME} |
| */ |
| public static boolean inServiceCatalog(int scopeId) { |
| return SERVICE_CATALOG.containsKey(scopeId); |
| } |
| |
| /** |
| * Check whether the given scope ID belongs service instance catalog |
| * |
| * @param scopeId represents an existing scope id. |
| * @return true is current scope set {@link ScopeDeclaration#catalog()} == {@link #SERVICE_INSTANCE_CATALOG_NAME} |
| */ |
| public static boolean inServiceInstanceCatalog(int scopeId) { |
| return SERVICE_INSTANCE_CATALOG.containsKey(scopeId); |
| } |
| |
| /** |
| * Check whether the given scope ID belongs endpoint catalog |
| * |
| * @param scopeId represents an existing scope id. |
| * @return true is current scope set {@link ScopeDeclaration#catalog()} == {@link #ENDPOINT_CATALOG_NAME} |
| */ |
| public static boolean inEndpointCatalog(int scopeId) { |
| return ENDPOINT_CATALOG.containsKey(scopeId); |
| } |
| |
| /** |
| * Check whether the given scope ID belongs service relation catalog |
| * |
| * @param scopeId represents an existing scope id. |
| * @return true is current scope set {@link ScopeDeclaration#catalog()} == {@link #SERVICE_RELATION_CATALOG_NAME} |
| */ |
| public static boolean inServiceRelationCatalog(int scopeId) { |
| return SERVICE_RELATION_CATALOG.containsKey(scopeId); |
| } |
| |
| /** |
| * Check whether the given scope ID belongs service instance relation catalog |
| * |
| * @param scopeId represents an existing scope id. |
| * @return true is current scope set {@link ScopeDeclaration#catalog()} == {@link #SERVICE_INSTANCE_RELATION_CATALOG_NAME} |
| */ |
| public static boolean inServiceInstanceRelationCatalog(int scopeId) { |
| return SERVICE_INSTANCE_RELATION_CATALOG.containsKey(scopeId); |
| } |
| |
| /** |
| * Check whether the given scope ID belongs endpoint relation catalog |
| * |
| * @param scopeId represents an existing scope id. |
| * @return true is current scope set {@link ScopeDeclaration#catalog()} == {@link #ENDPOINT_RELATION_CATALOG_NAME} |
| */ |
| public static boolean inEndpointRelationCatalog(int scopeId) { |
| return ENDPOINT_RELATION_CATALOG.containsKey(scopeId); |
| } |
| |
| /** |
| * Check whether the given scope ID belongs process catalog |
| * |
| * @param scopeId represents an existing scope id. |
| * @return true is current scope set {@link ScopeDeclaration#catalog()} == {@link #PROCESS_CATALOG_NAME} |
| */ |
| public static boolean inProcessCatalog(int scopeId) { |
| return PROCESS_CATALOG.containsKey(scopeId); |
| } |
| |
| /** |
| * Check whether the given scope ID belongs process relation catalog |
| * |
| * @param scopeId represents an existing scope id. |
| * @return true is current scope set {@link ScopeDeclaration#catalog()} == {@link #PROCESS_RELATION_CATALOG_NAME} |
| */ |
| public static boolean inProcessRelationCatalog(int scopeId) { |
| return PROCESS_RELATION_CATALOG.containsKey(scopeId); |
| } |
| |
| /** |
| * Get the catalog string name of the given scope |
| * |
| * @param scope id of the source scope. |
| * @return literal string name of the catalog owning the scope. Return `ALL` by default. |
| */ |
| public static String catalogOf(int scope) { |
| if (inServiceCatalog(scope)) { |
| return SERVICE_CATALOG_NAME; |
| } |
| if (inServiceInstanceCatalog(scope)) { |
| return SERVICE_INSTANCE_CATALOG_NAME; |
| } |
| if (inEndpointCatalog(scope)) { |
| return ENDPOINT_CATALOG_NAME; |
| } |
| if (inServiceRelationCatalog(scope)) { |
| return SERVICE_RELATION_CATALOG_NAME; |
| } |
| if (inServiceInstanceRelationCatalog(scope)) { |
| return SERVICE_INSTANCE_RELATION_CATALOG_NAME; |
| } |
| if (inEndpointRelationCatalog(scope)) { |
| return ENDPOINT_RELATION_CATALOG_NAME; |
| } |
| if (inProcessCatalog(scope)) { |
| return PROCESS_CATALOG_NAME; |
| } |
| if (inProcessRelationCatalog(scope)) { |
| return PROCESS_RELATION_CATALOG_NAME; |
| } |
| return "ALL"; |
| } |
| |
| /** |
| * Get the default columns defined in Scope. All those columns will forward to persistent entity. |
| * |
| * @param scopeName of the default columns |
| */ |
| public static List<ScopeDefaultColumn> getDefaultColumns(String scopeName) { |
| List<ScopeDefaultColumn> scopeDefaultColumns = SCOPE_COLUMNS.get(scopeName); |
| if (scopeDefaultColumns == null) { |
| throw new UnexpectedException("ScopeDefine name = " + scopeName + " not found."); |
| } |
| return scopeDefaultColumns; |
| } |
| } |