blob: 05d6e9a30299f703f94a6782f9cfc5f060426e1a [file] [log] [blame]
/*
* 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;
public static final int CACHE_ACCESS = 55;
public static final int CACHE_SLOW_ACCESS = 56;
/**
* 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;
}
}