org.opensearch.common.logging.JsonLogsIntegTestCase Maven / Gradle / Ivy
Show all versions of framework Show documentation
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch 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.
*/
/*
* Modifications Copyright OpenSearch Contributors. See
* GitHub history for details.
*/
package org.opensearch.common.logging;
import org.opensearch.common.SuppressForbidden;
import org.opensearch.test.rest.OpenSearchRestTestCase;
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Iterator;
import java.util.stream.Stream;
import static org.hamcrest.Matchers.emptyOrNullString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
/**
* Tests that extend this class verify that all json layout fields appear in the first few log lines after startup
* Fields available upon process startup: type
, timestamp
, level
, component
,
* message
, node.name
, cluster.name
.
* Whereas node.id
and cluster.uuid
are available later once the first clusterState has been received.
*
*
* node.name
, cluster.name
, node.id
, cluster.uuid
* should not change across all log lines
*
* Note that this won't pass for nodes in clusters that don't have the node name defined in opensearch.yml and start
* with DEBUG or TRACE level logging. Those nodes log a few lines before the node.name is set by LogConfigurator.setNodeName
.
*/
public abstract class JsonLogsIntegTestCase extends OpenSearchRestTestCase {
/**
* Number of lines in the log file to check for the node.name
, node.id
or cluster.uuid
. We don't
* just check the entire log file because it could be quite long
*/
private static final int LINES_TO_CHECK = 10;
/**
* The node name to expect in the log file.
*/
protected abstract org.hamcrest.Matcher nodeNameMatcher();
/**
* Open the log file. This is delegated to subclasses because the test
* framework doesn't have permission to read from the log file but
* subclasses can grant themselves that permission.
*/
protected abstract BufferedReader openReader(Path logFile);
public void testElementsPresentOnAllLinesOfLog() throws IOException {
JsonLogLine firstLine = findFirstLine();
assertNotNull(firstLine);
try (Stream stream = JsonLogsStream.from(openReader(getLogFile()))) {
stream.limit(LINES_TO_CHECK).forEach(jsonLogLine -> {
assertThat(jsonLogLine.type(), is(not(emptyOrNullString())));
assertThat(jsonLogLine.timestamp(), is(not(emptyOrNullString())));
assertThat(jsonLogLine.level(), is(not(emptyOrNullString())));
assertThat(jsonLogLine.component(), is(not(emptyOrNullString())));
assertThat(jsonLogLine.message(), is(not(emptyOrNullString())));
// all lines should have the same nodeName and clusterName
assertThat(jsonLogLine.nodeName(), nodeNameMatcher());
assertThat(jsonLogLine.clusterName(), equalTo(firstLine.clusterName()));
});
}
}
private JsonLogLine findFirstLine() throws IOException {
try (Stream stream = JsonLogsStream.from(openReader(getLogFile()))) {
return stream.findFirst().orElseThrow(() -> new AssertionError("no logs at all?!"));
}
}
public void testNodeIdAndClusterIdConsistentOnceAvailable() throws IOException {
try (Stream stream = JsonLogsStream.from(openReader(getLogFile()))) {
Iterator iterator = stream.iterator();
JsonLogLine firstLine = null;
while (iterator.hasNext()) {
JsonLogLine jsonLogLine = iterator.next();
if (jsonLogLine.nodeId() != null) {
firstLine = jsonLogLine;
}
}
assertNotNull(firstLine);
// once the nodeId and clusterId are received, they should be the same on remaining lines
int i = 0;
while (iterator.hasNext() && i++ < LINES_TO_CHECK) {
JsonLogLine jsonLogLine = iterator.next();
assertThat(jsonLogLine.nodeId(), equalTo(firstLine.nodeId()));
assertThat(jsonLogLine.clusterUuid(), equalTo(firstLine.clusterUuid()));
}
}
}
@SuppressForbidden(reason = "PathUtils doesn't have permission to read this file")
private Path getLogFile() {
String logFileString = System.getProperty("tests.logfile");
if (logFileString == null) {
fail(
"tests.logfile must be set to run this test. It is automatically "
+ "set by gradle. If you must set it yourself then it should be the absolute path to the "
+ "log file."
);
}
return Paths.get(logFileString);
}
}