Composer의 ThingWorx 모델 정의 > 시스템 > 로그 > ThingWorx Platform 로깅에 대한 OpenTelemetry > 외부 소스에서 로그 질의를 위한 사용자 정의 로그 검색 전략
외부 소스에서 로그 질의를 위한 사용자 정의 로그 검색 전략
로그 관찰성 기능은 시장에서 사용 가능한 다양한 타사 엔터프라이즈 로깅 공급자 응용 프로그램을 통해 수행할 수 있습니다. 이러한 응용 프로그램에는 로그를 푸시하고 검색하는 여러 방법이 있습니다.
OpenTelemetry를 사용하면 로그가 로깅 공급자 응용 프로그램으로 푸시됩니다.
이 로그 검색 전략의 주요 목적은 타사 소스에서 로그를 검색하여 이러한 로그를 Composer > 모니터링 > 로그 페이지에 표시하는 것입니다.
전체 구현의 일부로 ThingWorx는 다음을 제공합니다.
기본 전략 사물 DefaultLogRetrievalStrategyThing은 구성에 따라 ThingWorx 파일 로그 및 Sumo Logic에서 로그를 검색합니다.
Extension SDK를 사용하여 사용자 정의 로그 검색 전략을 개발합니다.
DefaultLogRetrievalStrategyThing은 시스템 객체입니다. 해당 구성만 업데이트할 수 있습니다. 사용자는 사용자 정의 로그 검색 전략을 구현하는 데 이 DefaultLogRetrievalStrategyThing 템플릿을 사용해서는 안 됩니다.
로그 검색은 DefaultLogRetrievalStrategyThing에서 제공되는 RetrieveLogs 서비스를 통해 처리됩니다. 로그 검색은 다음을 기반으로 합니다.
파일 로깅이 비활성화(DisableFileLoggingtrue로 설정됨)되고, OpenTelemetry가 활성화(EnableOpenTelemetryForLoggingtrue로 설정됨)된 경우 Sumo Logic에서만 로그가 검색됩니다.
다른 모든 경우에는 파일에서 로그가 검색됩니다.
로그 검색을 위한 사용자 정의 구현의 경우 RetrieveLogs 서비스는 다음 두 가지 방법으로 구현할 수 있습니다.
JavaScript 서비스를 사용한 Composer를 통해
a. LogRetrievalStrategy와 같은 기본 템플릿을 사용하여 Composer에서 사물을 만듭니다.
b. 서비스로 이동하여 RetriveLogs 서비스를 재정의합니다.
c. JavaScript 코드를 제공하여 타사 로깅 소프트웨어에서 로그를 검색합니다.
* 
일반적으로 콘텐츠 로더 함수 또는 이와 유사한 함수를 사용하여 타사 함수와 통신합니다.
Extension SDK로 ThingWorx에서 확장을 만들어
a. 최신 SDK(>=9.6.0)를 사용하여 Eclipse에서 확장을 만듭니다.
b. 기본 템플릿을 LogRetrievalStrategy로 사용하여 사물 템플릿(java 클래스)을 만듭니다.
해당 클래스는 로그 검색 전략 클래스를 확장해야 합니다.
c. 로그 검색 java 메소드를 재정의하고 사용자 정의 코드를 구현하여 타사 로깅 소프트웨어에서 로그를 검색합니다.
d. (선택 사항) 확장의 metadata.xml을 업데이트하고 사물을 만듭니다. 확장을 가져온 후 나중에 Composer에서 사물을 만들 수도 있습니다.
e. 확장을 빌드하고 확장을 ThingWorx로 가져옵니다.
두 경우 모두 사물이 있으면 로깅 하위 시스템에 이 사물을 LogRetrievalStrategy 사물로 설정해야 합니다.
이 자습서에서는 ThingWorx Extension을 만들기 위한 관련된 기본 사항에 대해서는 다루지 않습니다. 다음과 같은 가정이 있습니다.
ThingWorx Extension을 빌드하는 방법을 알고 있습니다.
LogRetrievalStrategy 사물 템플릿을 포함하는 Extension SDK v.9.6.0 이상이 있습니다.
ThingWorx Extension을 빌드하고 ThingWorx Platform으로 가져오는 방법을 알고 있습니다.
사용자 정의 로그 검색 전략 구현
1. Java로 사용자 정의 로그 검색 전략을 만들려면 먼저 로깅 전략 사물 템플릿을 만듭니다. 사물 템플릿은 Java 기반 알고리즘의 코드 베이스로 작동합니다. 사물 템플릿에 대한 클래스 정의는 다음과 같습니다.
@ThingworxBaseTemplateDefinition(name = "LogRetrievalStrategy")
public class CustomLogRetrievalStrategy extends LogRetrievalStrategy{
2. RetrieveLogs 메소드를 구현하고 재정의합니다.
@ThingworxServiceDefinition(
name = LoggingConstants.RETRIEVE_LOGS_STRATEGY_SERVICE_NAME,
isAllowOverride = true,
description = "Retrieve Logs from the given source",
category = "Queries")
@ThingworxServiceResult(name = "result", description = "Table entries", baseType = "INFOTABLE", aspects = { "dataShape:LogEntry" })
@Override
public InfoTable RetrieveLogs(
@ThingworxServiceParameter(
name = LoggingConstants.MAX_ITEMS,
description = "Maximum number of items to return",
baseType = "NUMBER",
aspects = { "defaultValue:" + RESTAPIConstants.DEFAULT_ITEM_COUNT }) Double maxItems,
@ThingworxServiceParameter(
name = LoggingConstants.START_DATE,
description = "Start time",
baseType = "DATETIME") DateTime startDate,
@ThingworxServiceParameter(
name = LoggingConstants.END_DATE,
description = "End time",
baseType = "DATETIME") DateTime endDate,
@ThingworxServiceParameter(
name = LoggingConstants.FROM_LOG_LEVEL,
description = "From log level",
baseType = "STRING") String fromLogLevel,
@ThingworxServiceParameter(
name = LoggingConstants.TO_LOG_LEVEL,
description = "To log level",
baseType = "STRING") String toLogLevel,
@ThingworxServiceParameter(
name = LoggingConstants.USER,
description = "Log messages for a specific user",
baseType = "USERNAME") String user,
@ThingworxServiceParameter(
name = LoggingConstants.THREAD,
description = "Log messages for a specific thread",
baseType = "STRING") String thread,
@ThingworxServiceParameter(
name = LoggingConstants.PLATFORM_ID,
description = "Log message from a specific instance",
baseType = "STRING") String platformId,
@ThingworxServiceParameter(
name = LoggingConstants.ORIGIN,
description = "Specific class or log source",
baseType = "STRING") String origin,
@ThingworxServiceParameter(
name = LoggingConstants.INSTANCE,
description = "Specific class or log source",
baseType = "STRING") String instance,
@ThingworxServiceParameter(
name = LoggingConstants.SEARCH_EXPRESSION,
description = "Keywords to search content",
baseType = "STRING") String searchExpression,
@ThingworxServiceParameter(
name = LoggingConstants.SORT_FIELD_NAME,
description = "Sort field name",
baseType = "STRING") String sortFieldName,
@ThingworxServiceParameter(
name = LoggingConstants.ASCENDING_SEARCH,
description = "Ascending search indicator (true = ascending, false = descending)",
baseType = "BOOLEAN") Boolean ascendingSearch,
@ThingworxServiceParameter(
name = LoggingConstants.OLDEST_FIRST,
description = "Search/sort from oldest to newest",
baseType = "BOOLEAN") Boolean oldestFirst,
@ThingworxServiceParameter(
name = LoggingConstants.IS_REGEX,
description = "The Search expression should be treated as REGEX",
baseType = "BOOLEAN",
aspects = { "defaultValue:" + false }) Boolean isRegex,
@ThingworxServiceParameter(
name = "logName",
description = "Keywords to search content",
baseType = "STRING",
aspects = { Aspects.ASPECT_ISREQUIRED + ":true", Aspects.ASPECT_SELECTOPTIONS +
":ApplicationLog:ApplicationLog|CommunicationLog:CommunicationLog|" +
"ConfigurationLog:ConfigurationLog|ScriptLog:ScriptLog|SecurityLog:SecurityLog" }) String logName)
throws Exception {

// Create InfoTable to hold results
InfoTable logEntriesTable = new InfoTable();

// Add Field Definitions to InfoTable.
logEntriesTable.addField(new FieldDefinition(LoggingConstants.CONTENT, BaseTypes.STRING));
logEntriesTable.addField(new FieldDefinition(LoggingConstants.USER, BaseTypes.STRING));
logEntriesTable.addField(new FieldDefinition(LoggingConstants.THREAD, BaseTypes.STRING));
logEntriesTable.addField(new FieldDefinition(LoggingConstants.PLATFORM_ID, BaseTypes.STRING));
logEntriesTable.addField(new FieldDefinition(LoggingConstants.ORIGIN, BaseTypes.STRING));
logEntriesTable.addField(new FieldDefinition(LoggingConstants.INSTANCE, BaseTypes.STRING));

// TODO: Custom Log Retrieval Strategy implementation here. Add each log entry as row to logEntriesTable

return logEntriesTable;
3. 확장의 metadata.xml 파일에 전략 사물을 만듭니다.
<Things>
<Thing
enabled="true"
name="CustomLogRetrievalStrategyThing"
published="true"
thingTemplate="CustomLogRetrievalStrategy">
</Thing>
</Things>
4. 확장을 패키지하고 빌드합니다.
5. ThingWorx Composer를 통해 확장을 가져옵니다.
6. ThingTemplate CustomLogRetrievalStrategy에서 사물을 만듭니다.
7. LoggingSubsystem > 구성 페이지로 이동합니다.
8. 6단계에서 만든 사물을 로그 검색 전략으로 선택합니다.
9. Composer > 모니터링 > ApplicationLog로 이동하여 로그가 외부 소스에서 검색되는지 여부를 확인합니다.
도움이 되셨나요?