You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ratis.apache.org by lj...@apache.org on 2020/01/31 09:02:30 UTC
[incubator-ratis] branch master updated: RATIS-755. Add a log dump
command line utility inside ratis. Contributed by Mukul Kumar Singh.
This is an automated email from the ASF dual-hosted git repository.
ljain pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-ratis.git
The following commit(s) were added to refs/heads/master by this push:
new 5e858b5 RATIS-755. Add a log dump command line utility inside ratis. Contributed by Mukul Kumar Singh.
5e858b5 is described below
commit 5e858b53fe5cd31c18c195fb92e7318e6f2d8318
Author: Lokesh Jain <lj...@apache.org>
AuthorDate: Fri Jan 31 14:32:19 2020 +0530
RATIS-755. Add a log dump command line utility inside ratis. Contributed by Mukul Kumar Singh.
---
pom.xml | 1 +
.../apache/ratis/server/impl/ServerProtoUtils.java | 23 +++--
.../ratis/server/raftlog/segmented/LogSegment.java | 4 +-
.../server/raftlog/segmented/SegmentedRaftLog.java | 2 +-
.../raftlog/segmented/SegmentedRaftLogWorker.java | 5 +-
.../ratis/server/storage/RaftStorageDirectory.java | 37 +++++---
ratis-tools/pom.xml | 100 ++++++++++++++++++++
.../org/apache/ratis/tools/ArithmeticLogDump.java | 51 ++++++++++
.../org/apache/ratis/tools/DefaultLogDump.java | 42 +++++++++
.../java/org/apache/ratis/tools/ParseRatisLog.java | 104 +++++++++++++++++++++
.../apache/ratis/tools/TestArithmeticLogDump.java | 90 ++++++++++++++++++
11 files changed, 430 insertions(+), 29 deletions(-)
diff --git a/pom.xml b/pom.xml
index 79f5d46..49cabeb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -57,6 +57,7 @@
<module>ratis-replicated-map</module>
<module>ratis-logservice</module>
<module>ratis-metrics</module>
+ <module>ratis-tools</module>
</modules>
<pluginRepositories>
diff --git a/ratis-server/src/main/java/org/apache/ratis/server/impl/ServerProtoUtils.java b/ratis-server/src/main/java/org/apache/ratis/server/impl/ServerProtoUtils.java
index 0f69f89..0bfb342 100644
--- a/ratis-server/src/main/java/org/apache/ratis/server/impl/ServerProtoUtils.java
+++ b/ratis-server/src/main/java/org/apache/ratis/server/impl/ServerProtoUtils.java
@@ -26,7 +26,6 @@ import org.apache.ratis.protocol.RaftGroupMemberId;
import org.apache.ratis.protocol.RaftPeer;
import org.apache.ratis.protocol.RaftPeerId;
import org.apache.ratis.server.protocol.TermIndex;
-import org.apache.ratis.statemachine.StateMachine;
import org.apache.ratis.thirdparty.com.google.protobuf.ByteString;
import org.apache.ratis.util.Preconditions;
import org.apache.ratis.util.ProtoUtils;
@@ -35,6 +34,7 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
+import java.util.function.Function;
import java.util.stream.Collectors;
import static org.apache.ratis.server.impl.RaftServerConstants.DEFAULT_CALLID;
@@ -69,26 +69,31 @@ public interface ServerProtoUtils {
return toLogEntryString(entry, null);
}
- static String toStateMachineLogEntryString(StateMachineLogEntryProto smLog, StateMachine stateMachine) {
- if (stateMachine != null) {
- return stateMachine.toStateMachineLogEntryString(smLog);
- }
+ static String toStateMachineLogEntryString(StateMachineLogEntryProto smLog,
+ Function<StateMachineLogEntryProto, String> function) {
final ByteString clientId = smLog.getClientId();
- return (clientId.isEmpty() ? "<empty clientId>" : ClientId.valueOf(clientId)) + ", cid=" + smLog.getCallId();
+ String callIdString = (clientId.isEmpty() ? "<empty clientId>" : ClientId.valueOf(clientId))
+ + ", cid=" + smLog.getCallId();
+
+ String smString = "";
+ if (function != null) {
+ smString = "\n\t State Machine: " + function.apply(smLog);
+ }
+ return callIdString + smString;
}
static String toLogEntryString(LogEntryProto entry,
- StateMachine stateMachine) {
+ Function<StateMachineLogEntryProto, String> function) {
if (entry == null) {
return null;
}
final String s;
if (entry.hasStateMachineLogEntry()) {
- s = ", " + toStateMachineLogEntryString(entry.getStateMachineLogEntry(), stateMachine);
+ s = ", " + toStateMachineLogEntryString(entry.getStateMachineLogEntry(), function);
} else if (entry.hasMetadataEntry()) {
final MetadataProto metadata = entry.getMetadataEntry();
- s = "(c" + metadata.getCommitIndex() + ")";
+ s = "(c:" + metadata.getCommitIndex() + ")";
} else {
s = "";
}
diff --git a/ratis-server/src/main/java/org/apache/ratis/server/raftlog/segmented/LogSegment.java b/ratis-server/src/main/java/org/apache/ratis/server/raftlog/segmented/LogSegment.java
index 19f997d..34552c2 100644
--- a/ratis-server/src/main/java/org/apache/ratis/server/raftlog/segmented/LogSegment.java
+++ b/ratis-server/src/main/java/org/apache/ratis/server/raftlog/segmented/LogSegment.java
@@ -50,7 +50,7 @@ import java.util.function.Consumer;
*
* This class will be protected by the {@link SegmentedRaftLog}'s read-write lock.
*/
-class LogSegment implements Comparable<Long> {
+public class LogSegment implements Comparable<Long> {
static final Logger LOG = LoggerFactory.getLogger(LogSegment.class);
static long getEntrySize(LogEntryProto entry) {
@@ -89,7 +89,7 @@ class LogSegment implements Comparable<Long> {
return new LogSegment(storage, false, start, end, raftLogMetrics);
}
- private static int readSegmentFile(File file, long start, long end,
+ public static int readSegmentFile(File file, long start, long end,
boolean isOpen, CorruptionPolicy corruptionPolicy,
RaftLogMetrics raftLogMetrics, Consumer<LogEntryProto> entryConsumer) throws
IOException {
diff --git a/ratis-server/src/main/java/org/apache/ratis/server/raftlog/segmented/SegmentedRaftLog.java b/ratis-server/src/main/java/org/apache/ratis/server/raftlog/segmented/SegmentedRaftLog.java
index eb91182..717c517 100644
--- a/ratis-server/src/main/java/org/apache/ratis/server/raftlog/segmented/SegmentedRaftLog.java
+++ b/ratis-server/src/main/java/org/apache/ratis/server/raftlog/segmented/SegmentedRaftLog.java
@@ -528,6 +528,6 @@ public class SegmentedRaftLog extends RaftLog {
@Override
public String toLogEntryString(LogEntryProto logEntry) {
- return ServerProtoUtils.toLogEntryString(logEntry, stateMachine);
+ return ServerProtoUtils.toLogEntryString(logEntry, stateMachine::toStateMachineLogEntryString);
}
}
diff --git a/ratis-server/src/main/java/org/apache/ratis/server/raftlog/segmented/SegmentedRaftLogWorker.java b/ratis-server/src/main/java/org/apache/ratis/server/raftlog/segmented/SegmentedRaftLogWorker.java
index d632bfb..a0d471e 100644
--- a/ratis-server/src/main/java/org/apache/ratis/server/raftlog/segmented/SegmentedRaftLogWorker.java
+++ b/ratis-server/src/main/java/org/apache/ratis/server/raftlog/segmented/SegmentedRaftLogWorker.java
@@ -455,7 +455,7 @@ class SegmentedRaftLogWorker implements Runnable {
this.stateMachineFuture = stateMachine.writeStateMachineData(entry);
} catch (Throwable e) {
LOG.error(name + ": writeStateMachineData failed for index " + entry.getIndex()
- + ", entry=" + ServerProtoUtils.toLogEntryString(entry, stateMachine), e);
+ + ", entry=" + ServerProtoUtils.toLogEntryString(entry, stateMachine::toStateMachineLogEntryString), e);
throw e;
}
}
@@ -510,7 +510,8 @@ class SegmentedRaftLogWorker implements Runnable {
@Override
public String toString() {
- return super.toString() + ": " + ServerProtoUtils.toLogEntryString(entry, stateMachine);
+ return super.toString() + ": " + ServerProtoUtils.
+ toLogEntryString(entry, stateMachine::toStateMachineLogEntryString);
}
}
diff --git a/ratis-server/src/main/java/org/apache/ratis/server/storage/RaftStorageDirectory.java b/ratis-server/src/main/java/org/apache/ratis/server/storage/RaftStorageDirectory.java
index 7a09442..5d57a20 100644
--- a/ratis-server/src/main/java/org/apache/ratis/server/storage/RaftStorageDirectory.java
+++ b/ratis-server/src/main/java/org/apache/ratis/server/storage/RaftStorageDirectory.java
@@ -18,6 +18,7 @@
package org.apache.ratis.server.storage;
import org.apache.ratis.server.impl.RaftServerConstants;
+import org.apache.ratis.server.raftlog.RaftLog;
import org.apache.ratis.util.AtomicFileOutputStream;
import org.apache.ratis.util.FileUtils;
import org.slf4j.Logger;
@@ -38,7 +39,6 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static java.nio.file.Files.newDirectoryStream;
-import static org.apache.ratis.server.impl.RaftServerConstants.INVALID_LOG_INDEX;
public class RaftStorageDirectory {
static final Logger LOG = LoggerFactory.getLogger(RaftStorageDirectory.class);
@@ -193,20 +193,9 @@ public class RaftStorageDirectory {
try (DirectoryStream<Path> stream =
Files.newDirectoryStream(getCurrentDir().toPath())) {
for (Path path : stream) {
- for (Pattern pattern : Arrays.asList(CLOSED_SEGMENT_REGEX, OPEN_SEGMENT_REGEX)) {
- Matcher matcher = pattern.matcher(path.getFileName().toString());
- if (matcher.matches()) {
- if (pattern == OPEN_SEGMENT_REGEX && Files.size(path) == 0L) {
- Files.delete(path);
- LOG.info("Delete zero size file " + path);
- break;
- }
- final long startIndex = Long.parseLong(matcher.group(1));
- final long endIndex = matcher.groupCount() == 2 ?
- Long.parseLong(matcher.group(2)) : INVALID_LOG_INDEX;
- list.add(new LogPathAndIndex(path, startIndex, endIndex));
- break;
- }
+ LogPathAndIndex lpi = processOnePath(path);
+ if (lpi != null) {
+ list.add(lpi);
}
}
}
@@ -214,6 +203,24 @@ public class RaftStorageDirectory {
return list;
}
+ public static LogPathAndIndex processOnePath(Path path) throws IOException {
+ for (Pattern pattern : Arrays.asList(CLOSED_SEGMENT_REGEX, OPEN_SEGMENT_REGEX)) {
+ Matcher matcher = pattern.matcher(path.getFileName().toString());
+ if (matcher.matches()) {
+ if (pattern == OPEN_SEGMENT_REGEX && Files.size(path) == 0L) {
+ Files.delete(path);
+ LOG.info("Delete zero size file " + path);
+ return null;
+ }
+ final long startIndex = Long.parseLong(matcher.group(1));
+ final long endIndex = matcher.groupCount() == 2 ?
+ Long.parseLong(matcher.group(2)) : RaftLog.INVALID_LOG_INDEX;
+ return new LogPathAndIndex(path, startIndex, endIndex);
+ }
+ }
+ return null;
+ }
+
/**
* Check to see if current/ directory is empty.
*/
diff --git a/ratis-tools/pom.xml b/ratis-tools/pom.xml
new file mode 100644
index 0000000..476c6c1
--- /dev/null
+++ b/ratis-tools/pom.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed 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. See accompanying LICENSE file.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>ratis</artifactId>
+ <groupId>org.apache.ratis</groupId>
+ <version>0.5.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>ratis-tools</artifactId>
+ <name>Apache Ratis Tools</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.ratis</groupId>
+ <artifactId>ratis-server</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.ratis</groupId>
+ <artifactId>ratis-proto</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.ratis</groupId>
+ <artifactId>ratis-common</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.ratis</groupId>
+ <artifactId>ratis-examples</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.ratis</groupId>
+ <artifactId>ratis-common</artifactId>
+ <scope>test</scope>
+ <type>test-jar</type>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.ratis</groupId>
+ <artifactId>ratis-server</artifactId>
+ <scope>test</scope>
+ <type>test-jar</type>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-shade-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>shade</goal>
+ </goals>
+ <configuration>
+ <dependencyReducedPomLocation>${project.build.directory}/dependency-reduced-pom.xml</dependencyReducedPomLocation>
+ <shadedArtifactAttached>true</shadedArtifactAttached>
+ <transformers>
+ <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
+ <mainClass>org.apache.ratis.tools.ArithmeticLogDump</mainClass>
+ </transformer>
+ </transformers>
+ <filters>
+ <filter>
+ <artifact>*:*</artifact>
+ <excludes>
+ <exlcude>META-INF/*.SF</exlcude>
+ <exclude>META-INF/*.DSA</exclude>
+ <exclude>META-INF/*.RSA</exclude>
+ </excludes>
+ </filter>
+ </filters>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/ratis-tools/src/main/java/org/apache/ratis/tools/ArithmeticLogDump.java b/ratis-tools/src/main/java/org/apache/ratis/tools/ArithmeticLogDump.java
new file mode 100644
index 0000000..6cc9438
--- /dev/null
+++ b/ratis-tools/src/main/java/org/apache/ratis/tools/ArithmeticLogDump.java
@@ -0,0 +1,51 @@
+/*
+ * 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.ratis.tools;
+
+import org.apache.ratis.examples.arithmetic.AssignmentMessage;
+import org.apache.ratis.proto.RaftProtos.StateMachineLogEntryProto;
+
+import java.io.File;
+
+/**
+ * Utility to dump log segments for Arithmetic State Machine.
+ */
+public final class ArithmeticLogDump {
+ private ArithmeticLogDump() {
+
+ }
+
+ public static void main(String[] args) throws Exception {
+ String filePath = args[0];
+ System.out.println("file path is " + filePath);
+ File logFile = new File(filePath);
+
+ ParseRatisLog.Builder builder = new ParseRatisLog.Builder();
+ ParseRatisLog prl = builder.setSegmentFile(logFile)
+ .setSMLogToString(ArithmeticLogDump::smToArithmeticLogString)
+ .build();
+
+ prl.dumpSegmentFile();
+ }
+
+ private static String smToArithmeticLogString(StateMachineLogEntryProto logEntryProto) {
+ AssignmentMessage message = new AssignmentMessage(logEntryProto.getLogData());
+ return message.toString();
+ }
+}
diff --git a/ratis-tools/src/main/java/org/apache/ratis/tools/DefaultLogDump.java b/ratis-tools/src/main/java/org/apache/ratis/tools/DefaultLogDump.java
new file mode 100644
index 0000000..451d205
--- /dev/null
+++ b/ratis-tools/src/main/java/org/apache/ratis/tools/DefaultLogDump.java
@@ -0,0 +1,42 @@
+/*
+ * 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.ratis.tools;
+
+import java.io.File;
+
+/**
+ * Default log dump tool to dump log entries for any state machine.
+ */
+public final class DefaultLogDump {
+ private DefaultLogDump() {
+
+ }
+
+ public static void main(String[] args) throws Exception {
+ String filePath = args[0];
+ System.out.println("file path is " + filePath);
+ File logFile = new File(filePath);
+
+ ParseRatisLog.Builder builder = new ParseRatisLog.Builder();
+ ParseRatisLog prl = builder.setSegmentFile(logFile)
+ .build();
+
+ prl.dumpSegmentFile();
+ }
+}
diff --git a/ratis-tools/src/main/java/org/apache/ratis/tools/ParseRatisLog.java b/ratis-tools/src/main/java/org/apache/ratis/tools/ParseRatisLog.java
new file mode 100644
index 0000000..6ac3829
--- /dev/null
+++ b/ratis-tools/src/main/java/org/apache/ratis/tools/ParseRatisLog.java
@@ -0,0 +1,104 @@
+/*
+ * 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.ratis.tools;
+
+import org.apache.ratis.proto.RaftProtos.StateMachineLogEntryProto;
+import org.apache.ratis.proto.RaftProtos.LogEntryProto;
+import org.apache.ratis.server.RaftServerConfigKeys;
+import org.apache.ratis.server.impl.ServerProtoUtils;
+import org.apache.ratis.server.raftlog.segmented.LogSegment;
+import org.apache.ratis.server.storage.RaftStorageDirectory;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.function.Function;
+
+public final class ParseRatisLog {
+
+ private final File file;
+ private final Function<StateMachineLogEntryProto, String> smLogToString;
+
+ private long numConfEntries;
+ private long numMetadataEntries;
+ private long numStateMachineEntries;
+ private long numInvalidEntries;
+
+ private ParseRatisLog(File f , Function<StateMachineLogEntryProto, String> smLogToString) {
+ this.file = f;
+ this.smLogToString = smLogToString;
+ this.numConfEntries = 0;
+ this.numMetadataEntries = 0;
+ this.numStateMachineEntries = 0;
+ this.numInvalidEntries = 0;
+ }
+
+ public void dumpSegmentFile() throws IOException {
+ RaftStorageDirectory.LogPathAndIndex pi = RaftStorageDirectory.processOnePath(file.toPath());
+ if (pi == null) {
+ System.out.println("Invalid segment file");
+ return;
+ }
+
+ System.out.println("Processing Raft Log file: " + file.getAbsolutePath() + " size:" + file.length());
+ final int entryCount = LogSegment.readSegmentFile(file, pi.startIndex, pi.endIndex, pi.isOpen(),
+ RaftServerConfigKeys.Log.CorruptionPolicy.EXCEPTION, null, this::processLogEntry);
+ System.out.println("Num Total Entries: " + entryCount);
+ System.out.println("Num Conf Entries: " + numConfEntries);
+ System.out.println("Num Metadata Entries: " + numMetadataEntries);
+ System.out.println("Num StateMachineEntries Entries: " + numStateMachineEntries);
+ System.out.println("Num Invalid Entries: " + numInvalidEntries);
+ }
+
+
+ private void processLogEntry(LogEntryProto proto) {
+ if (proto.hasConfigurationEntry()) {
+ numConfEntries++;
+ } else if (proto.hasMetadataEntry()) {
+ numMetadataEntries++;
+ } else if (proto.hasStateMachineLogEntry()) {
+ numStateMachineEntries++;
+ } else {
+ System.out.println("Found invalid entry" + proto.toString());
+ numInvalidEntries++;
+ }
+
+ String str = ServerProtoUtils.toLogEntryString(proto, smLogToString);
+ System.out.println(str);
+ }
+
+ public static class Builder {
+ private File file = null;
+ private Function<StateMachineLogEntryProto, String> smLogToString = null;
+
+
+ public Builder setSegmentFile(File segmentFile) {
+ this.file = segmentFile;
+ return this;
+ }
+
+ public Builder setSMLogToString(Function<StateMachineLogEntryProto, String> smLogToStr) {
+ this.smLogToString = smLogToStr;
+ return this;
+ }
+
+ public ParseRatisLog build() {
+ return new ParseRatisLog(file, smLogToString);
+ }
+ }
+}
diff --git a/ratis-tools/src/test/java/org/apache/ratis/tools/TestArithmeticLogDump.java b/ratis-tools/src/test/java/org/apache/ratis/tools/TestArithmeticLogDump.java
new file mode 100644
index 0000000..dc215ac
--- /dev/null
+++ b/ratis-tools/src/test/java/org/apache/ratis/tools/TestArithmeticLogDump.java
@@ -0,0 +1,90 @@
+/**
+ * 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.ratis.tools;
+
+import org.apache.log4j.Level;
+import org.apache.ratis.BaseTest;
+import org.apache.ratis.MiniRaftCluster;
+import org.apache.ratis.RaftTestUtil;
+import org.apache.ratis.conf.RaftProperties;
+import org.apache.ratis.server.RaftServerConfigKeys;
+import org.apache.ratis.server.impl.RaftServerImpl;
+import org.apache.ratis.server.simulation.MiniRaftClusterWithSimulatedRpc;
+import org.apache.ratis.server.storage.RaftStorageDirectory;
+import org.apache.ratis.statemachine.SimpleStateMachine4Testing;
+import org.apache.ratis.statemachine.StateMachine;
+import org.apache.ratis.util.Log4jUtils;
+import org.apache.ratis.util.TimeDuration;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+public class TestArithmeticLogDump extends BaseTest {
+ static {
+ Log4jUtils.setLogLevel(RaftServerImpl.LOG, Level.DEBUG);
+ }
+
+ public static final int NUM_SERVERS = 1;
+
+ protected static final RaftProperties properties = new RaftProperties();
+
+ private final MiniRaftClusterWithSimulatedRpc cluster = MiniRaftClusterWithSimulatedRpc
+ .FACTORY.newCluster(NUM_SERVERS, getProperties());
+
+ public RaftProperties getProperties() {
+ RaftServerConfigKeys.Rpc
+ .setSlownessTimeout(properties, TimeDuration.valueOf(1, TimeUnit.SECONDS));
+ properties.setClass(MiniRaftCluster.STATEMACHINE_CLASS_KEY,
+ SimpleStateMachine4Testing.class, StateMachine.class);
+ return properties;
+ }
+
+ @Before
+ public void setup() throws IOException {
+ Assert.assertNull(cluster.getLeader());
+ cluster.start();
+ }
+
+ @After
+ public void tearDown() {
+ if (cluster != null) {
+ cluster.shutdown();
+ }
+ }
+
+ @Test
+ public void testLogDump() throws Exception {
+ RaftServerImpl leaderServer = RaftTestUtil.waitForLeader(cluster);
+ List<RaftStorageDirectory.LogPathAndIndex> files =
+ leaderServer.getState().getStorage().getStorageDir().getLogSegmentFiles();
+ Assert.assertEquals(1, files.size());
+ cluster.shutdown();
+
+ ParseRatisLog.Builder builder = new ParseRatisLog.Builder();
+ ParseRatisLog prl = builder.setSegmentFile(files.get(0).getPath().toFile())
+ .build();
+
+ prl.dumpSegmentFile();
+ }
+}