mirror of
https://github.com/Qortal/AT.git
synced 2025-01-30 02:42:14 +00:00
Improved logging support
We now use a logger factory, which means loggers can be created per class. This allows use of 'wrapped' Apache log4j2 loggers with the added benefit of more accurate class/line-number reporting.
This commit is contained in:
parent
ee2a81430c
commit
466ffa4d4d
11
Java/src/main/java/org/ciyam/at/AtLogger.java
Normal file
11
Java/src/main/java/org/ciyam/at/AtLogger.java
Normal file
@ -0,0 +1,11 @@
|
||||
package org.ciyam.at;
|
||||
|
||||
public interface AtLogger {
|
||||
|
||||
void error(final String message);
|
||||
|
||||
void debug(final String message);
|
||||
|
||||
void echo(final String message);
|
||||
|
||||
}
|
7
Java/src/main/java/org/ciyam/at/AtLoggerFactory.java
Normal file
7
Java/src/main/java/org/ciyam/at/AtLoggerFactory.java
Normal file
@ -0,0 +1,7 @@
|
||||
package org.ciyam.at;
|
||||
|
||||
public interface AtLoggerFactory {
|
||||
|
||||
AtLogger create(final Class<?> loggerName);
|
||||
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
package org.ciyam.at;
|
||||
|
||||
public interface LoggerInterface {
|
||||
|
||||
public void error(String message);
|
||||
|
||||
public void debug(String message);
|
||||
|
||||
public void echo(String message);
|
||||
|
||||
}
|
@ -126,7 +126,8 @@ public class MachineState {
|
||||
private boolean isFirstOpCodeAfterSleeping;
|
||||
|
||||
private API api;
|
||||
private LoggerInterface logger;
|
||||
private AtLoggerFactory loggerFactory;
|
||||
private AtLogger logger;
|
||||
|
||||
// NOTE: These are package-scope to allow easy access/operations in Opcode/FunctionCode.
|
||||
/* package */ ByteBuffer codeByteBuffer;
|
||||
@ -137,7 +138,7 @@ public class MachineState {
|
||||
// Constructors
|
||||
|
||||
/** For internal use when recreating a machine state */
|
||||
private MachineState(API api, LoggerInterface logger, byte[] headerBytes) {
|
||||
private MachineState(byte[] headerBytes, API api, AtLoggerFactory loggerFactory) {
|
||||
if (headerBytes.length != HEADER_LENGTH)
|
||||
throw new IllegalArgumentException("headerBytes length " + headerBytes.length + " incorrect, expected " + HEADER_LENGTH);
|
||||
|
||||
@ -190,12 +191,13 @@ public class MachineState {
|
||||
this.currentBalance = 0;
|
||||
this.previousBalance = 0;
|
||||
this.steps = 0;
|
||||
this.logger = logger;
|
||||
this.loggerFactory = loggerFactory;
|
||||
this.logger = loggerFactory.create(MachineState.class);
|
||||
}
|
||||
|
||||
/** For creating a new machine state */
|
||||
public MachineState(API api, byte[] creationBytes) {
|
||||
this(api, null, Arrays.copyOfRange(creationBytes, 0, HEADER_LENGTH));
|
||||
public MachineState(API api, AtLoggerFactory loggerFactory, byte[] creationBytes) {
|
||||
this(Arrays.copyOfRange(creationBytes, 0, HEADER_LENGTH), api, loggerFactory);
|
||||
|
||||
int expectedLength = HEADER_LENGTH + this.numCodePages * this.constants.CODE_PAGE_SIZE + this.numDataPages * this.constants.DATA_PAGE_SIZE;
|
||||
if (creationBytes.length != expectedLength)
|
||||
@ -210,8 +212,8 @@ public class MachineState {
|
||||
}
|
||||
|
||||
/** For creating a new machine state - used in tests */
|
||||
public MachineState(API api, LoggerInterface logger, byte[] headerBytes, byte[] codeBytes, byte[] dataBytes) {
|
||||
this(api, logger, headerBytes);
|
||||
public MachineState(API api, AtLoggerFactory loggerFactory, byte[] headerBytes, byte[] codeBytes, byte[] dataBytes) {
|
||||
this(headerBytes, api, loggerFactory);
|
||||
|
||||
if (codeBytes.length > this.numCodePages * this.constants.CODE_PAGE_SIZE)
|
||||
throw new IllegalArgumentException("Number of code pages too small to hold code bytes");
|
||||
@ -342,7 +344,11 @@ public class MachineState {
|
||||
return this.api;
|
||||
}
|
||||
|
||||
public LoggerInterface getLogger() {
|
||||
public AtLoggerFactory getLoggerFactory() {
|
||||
return this.loggerFactory;
|
||||
}
|
||||
|
||||
/* package */ AtLogger getLogger() {
|
||||
return this.logger;
|
||||
}
|
||||
|
||||
@ -516,13 +522,13 @@ public class MachineState {
|
||||
}
|
||||
|
||||
/** For restoring a previously serialized machine state */
|
||||
public static MachineState fromBytes(API api, LoggerInterface logger, byte[] bytes, byte[] codeBytes) {
|
||||
public static MachineState fromBytes(API api, AtLoggerFactory loggerFactory, byte[] bytes, byte[] codeBytes) {
|
||||
ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
|
||||
|
||||
byte[] headerBytes = new byte[HEADER_LENGTH];
|
||||
byteBuffer.get(headerBytes);
|
||||
|
||||
MachineState state = new MachineState(api, logger, headerBytes);
|
||||
MachineState state = new MachineState(headerBytes, api, loggerFactory);
|
||||
|
||||
if (codeBytes.length != state.codeByteBuffer.capacity())
|
||||
throw new IllegalStateException("Passed codeBytes does not match length in header");
|
||||
|
@ -62,7 +62,7 @@ public class MiscTests extends ExecutableTest {
|
||||
byte[] codeBytes = codeByteBuffer.array();
|
||||
byte[] dataBytes = new byte[0];
|
||||
|
||||
state = new MachineState(api, logger, headerBytes, codeBytes, dataBytes);
|
||||
state = new MachineState(api, loggerFactory, headerBytes, codeBytes, dataBytes);
|
||||
|
||||
assertTrue(state.isFrozen());
|
||||
assertEquals((Long) (minActivationAmount - 1L), state.getFrozenBalance());
|
||||
|
@ -102,12 +102,12 @@ public class SerializationTests extends ExecutableTest {
|
||||
byte[] codeBytes = codeByteBuffer.array();
|
||||
byte[] dataBytes = dataByteBuffer.array();
|
||||
|
||||
state = new MachineState(api, logger, headerBytes, codeBytes, dataBytes);
|
||||
state = new MachineState(api, loggerFactory, headerBytes, codeBytes, dataBytes);
|
||||
packedState = state.toBytes();
|
||||
|
||||
byte[] creationBytes = MachineState.toCreationBytes(TestUtils.VERSION, codeBytes, dataBytes, TestUtils.NUM_CALL_STACK_PAGES, TestUtils.NUM_USER_STACK_PAGES, TestUtils.MIN_ACTIVATION_AMOUNT);
|
||||
|
||||
MachineState restoredState = new MachineState(api, creationBytes);
|
||||
MachineState restoredState = new MachineState(api, loggerFactory, creationBytes);
|
||||
byte[] packedRestoredSate = restoredState.toBytes();
|
||||
|
||||
assertTrue(Arrays.equals(packedState, packedRestoredSate));
|
||||
@ -118,14 +118,14 @@ public class SerializationTests extends ExecutableTest {
|
||||
byte[] codeBytes = codeByteBuffer.array();
|
||||
byte[] dataBytes = new byte[0];
|
||||
|
||||
state = new MachineState(api, logger, headerBytes, codeBytes, dataBytes);
|
||||
state = new MachineState(api, loggerFactory, headerBytes, codeBytes, dataBytes);
|
||||
|
||||
return executeAndCheck(state);
|
||||
}
|
||||
|
||||
private byte[] continueSimulation(byte[] savedState) {
|
||||
byte[] codeBytes = codeByteBuffer.array();
|
||||
state = MachineState.fromBytes(api, logger, savedState, codeBytes);
|
||||
state = MachineState.fromBytes(api, loggerFactory, savedState, codeBytes);
|
||||
|
||||
// Pretend we're on next block
|
||||
api.bumpCurrentBlockHeight();
|
||||
@ -141,7 +141,7 @@ public class SerializationTests extends ExecutableTest {
|
||||
byte[] codeBytes = state.getCodeBytes();
|
||||
|
||||
// Rebuild new MachineState using fetched state & bytes
|
||||
MachineState restoredState = MachineState.fromBytes(api, logger, stateBytes, codeBytes);
|
||||
MachineState restoredState = MachineState.fromBytes(api, loggerFactory, stateBytes, codeBytes);
|
||||
// Extract rebuilt state and code bytes
|
||||
byte[] restoredStateBytes = restoredState.toBytes();
|
||||
byte[] restoredCodeBytes = state.getCodeBytes();
|
||||
|
@ -14,7 +14,7 @@ public abstract class ExecutableTest {
|
||||
private static final int DATA_OFFSET = MachineState.HEADER_LENGTH; // code bytes are not present
|
||||
private static final int CALL_STACK_OFFSET = DATA_OFFSET + TestUtils.NUM_DATA_PAGES * MachineState.VALUE_SIZE;
|
||||
|
||||
public TestLogger logger;
|
||||
public TestLoggerFactory loggerFactory;
|
||||
public TestAPI api;
|
||||
public MachineState state;
|
||||
public ByteBuffer codeByteBuffer;
|
||||
@ -32,7 +32,7 @@ public abstract class ExecutableTest {
|
||||
|
||||
@Before
|
||||
public void beforeTest() {
|
||||
logger = new TestLogger();
|
||||
loggerFactory = new TestLoggerFactory();
|
||||
api = new TestAPI();
|
||||
codeByteBuffer = ByteBuffer.allocate(TestUtils.NUM_CODE_PAGES * MachineState.OPCODE_SIZE);
|
||||
dataByteBuffer = ByteBuffer.allocate(TestUtils.NUM_DATA_PAGES * MachineState.VALUE_SIZE);
|
||||
@ -47,7 +47,7 @@ public abstract class ExecutableTest {
|
||||
codeByteBuffer = null;
|
||||
dataByteBuffer = null;
|
||||
api = null;
|
||||
logger = null;
|
||||
loggerFactory = null;
|
||||
}
|
||||
|
||||
protected void execute(boolean onceOnly) {
|
||||
@ -58,12 +58,12 @@ public abstract class ExecutableTest {
|
||||
if (packedState == null) {
|
||||
// First time
|
||||
System.out.println("First execution - deploying...");
|
||||
state = new MachineState(api, logger, headerBytes, codeBytes, dataBytes);
|
||||
state = new MachineState(api, loggerFactory, headerBytes, codeBytes, dataBytes);
|
||||
packedState = state.toBytes();
|
||||
}
|
||||
|
||||
do {
|
||||
state = MachineState.fromBytes(api, logger, packedState, codeBytes);
|
||||
state = MachineState.fromBytes(api, loggerFactory, packedState, codeBytes);
|
||||
|
||||
System.out.println("Starting execution round!");
|
||||
System.out.println("Current block height: " + api.getCurrentBlockHeight());
|
||||
|
@ -1,8 +1,9 @@
|
||||
package org.ciyam.at.test;
|
||||
|
||||
import org.ciyam.at.LoggerInterface;
|
||||
import org.ciyam.at.AtLogger;
|
||||
|
||||
public class TestLogger implements AtLogger {
|
||||
|
||||
public class TestLogger implements LoggerInterface {
|
||||
@Override
|
||||
public void error(String message) {
|
||||
System.err.println("ERROR: " + message);
|
||||
|
13
Java/src/test/java/org/ciyam/at/test/TestLoggerFactory.java
Normal file
13
Java/src/test/java/org/ciyam/at/test/TestLoggerFactory.java
Normal file
@ -0,0 +1,13 @@
|
||||
package org.ciyam.at.test;
|
||||
|
||||
import org.ciyam.at.AtLogger;
|
||||
import org.ciyam.at.AtLoggerFactory;
|
||||
|
||||
public class TestLoggerFactory implements AtLoggerFactory {
|
||||
|
||||
@Override
|
||||
public AtLogger create(Class<?> loggerName) {
|
||||
return new TestLogger();
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user