/* * Copyright OpenSearch Contributors * SPDX-License-Identifier: Apache-2.0 */ package org.opensearch.performanceanalyzer.rca; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.nio.channels.FileChannel; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Scanner; import org.apache.logging.log4j.core.LoggerContext; import org.apache.logging.log4j.core.appender.FileAppender; import org.jooq.tools.json.JSONObject; import org.opensearch.performanceanalyzer.AppContext; import org.opensearch.performanceanalyzer.commons.collectors.StatsCollector; import org.opensearch.performanceanalyzer.commons.event_process.Event; import org.opensearch.performanceanalyzer.commons.metrics.AllMetrics; import org.opensearch.performanceanalyzer.commons.stats.ServiceMetrics; import org.opensearch.performanceanalyzer.commons.stats.measurements.MeasurementSet; import org.opensearch.performanceanalyzer.rca.framework.core.ConnectedComponent; import org.opensearch.performanceanalyzer.rca.framework.core.Node; import org.opensearch.performanceanalyzer.reader.ClusterDetailsEventProcessor; public class RcaTestHelper { public static List<String> getAllLinesFromStatsLog() { try { String statsLog = getLogFilePath(LogType.StatsLog); if (statsLog == null) { return Collections.emptyList(); } return Files.readAllLines(Paths.get(statsLog)); } catch (IOException e) { e.printStackTrace(); } return Collections.EMPTY_LIST; } public static List<String> getAllLinesWithMatchingString(String pattern) { List<String> matches = new ArrayList<>(); for (String line : getAllLinesFromStatsLog()) { if (line.contains(pattern)) { matches.add(line); } } return matches; } public static List<String> getAllLinesFromLog(LogType logType) { try { String logFilePath = getLogFilePath(logType); if (logFilePath == null) { return Collections.emptyList(); } return Files.readAllLines(Paths.get(logFilePath)); } catch (IOException e) { e.printStackTrace(); } return Collections.EMPTY_LIST; } public static List<String> getAllLogLinesWithMatchingString(LogType logType, String pattern) { List<String> matches = new ArrayList<>(); for (String line : getAllLinesFromLog(logType)) { if (line.contains(pattern)) { matches.add(line); } } return matches; } public enum LogType { PerformanceAnalyzerLog, StatsLog } public static String getLogFilePath(LogType logType) { System.out.println(LoggerContext.getContext().getRootLogger().getAppenders()); org.apache.logging.log4j.core.Logger logger = null; if (logType == LogType.StatsLog) { logger = LoggerContext.getContext().getLogger("stats_log"); } else { logger = LoggerContext.getContext().getRootLogger(); } FileAppender fileAppender = (FileAppender) logger.getAppenders().get(logType.name()); return fileAppender == null ? null : fileAppender.getFileName(); } public static void cleanUpLogs() { String paLog = getLogFilePath(LogType.PerformanceAnalyzerLog); if (paLog != null) { truncate(Paths.get(paLog).toFile()); } String statsLog = getLogFilePath(LogType.StatsLog); if (statsLog != null) { truncate(Paths.get(statsLog).toFile()); } } public static void setEvaluationTimeForAllNodes( List<ConnectedComponent> connectedComponents, long val) { for (ConnectedComponent connectedComponent : connectedComponents) { for (Node node : connectedComponent.getAllNodes()) { node.setEvaluationIntervalSeconds(val); } } } public static AppContext setMyIp(String ip, AllMetrics.NodeRole nodeRole) { final String separator = System.lineSeparator(); JSONObject jtime = new JSONObject(); jtime.put("current_time", 1566414001749L); JSONObject jOverrides = new JSONObject(); long overridesTimestamp = System.currentTimeMillis(); JSONObject jNode = new JSONObject(); jNode.put(AllMetrics.NodeDetailColumns.ID.toString(), "4sqG_APMQuaQwEW17_6zwg"); jNode.put(AllMetrics.NodeDetailColumns.HOST_ADDRESS.toString(), ip); jNode.put(AllMetrics.NodeDetailColumns.ROLE.toString(), nodeRole); jNode.put( AllMetrics.NodeDetailColumns.IS_CLUSTER_MANAGER_NODE, nodeRole == AllMetrics.NodeRole.ELECTED_CLUSTER_MANAGER ? true : false); ClusterDetailsEventProcessor eventProcessor = new ClusterDetailsEventProcessor(); StringBuilder nodeDetails = new StringBuilder(); nodeDetails.append(jtime); nodeDetails.append(separator); nodeDetails.append(jOverrides); nodeDetails.append(separator); nodeDetails.append(overridesTimestamp); nodeDetails.append(separator); nodeDetails.append(jNode); eventProcessor.processEvent(new Event("", nodeDetails.toString(), 0)); AppContext appContext = new AppContext(); appContext.setClusterDetailsEventProcessor(eventProcessor); return appContext; } public static void truncate(File file) { try (FileChannel outChan = new FileOutputStream(file, false).getChannel()) { outChan.truncate(0); } catch (FileNotFoundException e) { System.out.println(file.getName() + " does not exist."); } catch (IOException e) { e.printStackTrace(); } } public static void updateConfFileForMutedComponents( String rcaConfPath, List<String> mutedComponents, String componentKey) throws Exception { // create the config json Object from rca config file Scanner scanner = new Scanner(new FileInputStream(rcaConfPath), StandardCharsets.UTF_8.name()); String jsonText = scanner.useDelimiter("\\A").next(); ObjectMapper mapper = new ObjectMapper(); mapper.enable(JsonParser.Feature.ALLOW_COMMENTS); mapper.enable(SerializationFeature.INDENT_OUTPUT); JsonNode configObject = mapper.readTree(jsonText); // update the `MUTED_RCAS_CONFIG` value in config Object ArrayNode array = mapper.valueToTree(mutedComponents); ((ObjectNode) configObject).putArray(componentKey).addAll(array); mapper.writeValue(new FileOutputStream(rcaConfPath), configObject); } public static boolean verify(MeasurementSet measurementSet) throws InterruptedException { final int MAX_TIME_TO_WAIT_MILLIS = 10_000; int waited_for_millis = 0; while (waited_for_millis++ < MAX_TIME_TO_WAIT_MILLIS) { if (ServiceMetrics.STATS_REPORTER.isMeasurementCollected(measurementSet)) { return true; } Thread.sleep(1); } return false; } public static boolean verifyStatException(String exceptionCode) throws InterruptedException { final int MAX_TIME_TO_WAIT_MILLIS = 10_000; int waited_for_millis = 0; while (waited_for_millis++ < MAX_TIME_TO_WAIT_MILLIS) { if (StatsCollector.instance().getCounters().containsKey(exceptionCode)) { return true; } Thread.sleep(1); } return false; } }