Skip to content

Commit

Permalink
Optimize logging by creating a debug flag (#1054)
Browse files Browse the repository at this point in the history
* Optimize debug to reduce array allocation due to var-args

* Optimize logging by creating a debug flag
  • Loading branch information
justin-tay committed Jun 11, 2024
1 parent 2d645e6 commit 028710e
Show file tree
Hide file tree
Showing 50 changed files with 95 additions and 53 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,7 @@ The following is sample output from the Hierarchical format.
| `locale` | The locale to use for generating messages in the `ValidationMessage`. Note that this value is copied from `SchemaValidatorsConfig` for each execution. | `Locale.getDefault()`
| `failFast` | Whether to return failure immediately when an assertion is generated. Note that this value is copied from `SchemaValidatorsConfig` for each execution but is automatically set to `true` for the Boolean and Flag output formats. | `false`
| `formatAssertionsEnabled` | The default is to generate format assertions from Draft 4 to Draft 7 and to only generate annotations from Draft 2019-09. Setting to `true` or `false` will override the default behavior. | `null`
| `debugEnabled` | Controls whether debug logging is enabled for logging the node information when processing. Note that this will generate a lot of logs that will affect performance. | `false`

### Schema Validators Configuration

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNo

protected Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
JsonNodePath instanceLocation, boolean walk) {
debug(logger, node, rootNode, instanceLocation);
debug(logger, executionContext, node, rootNode, instanceLocation);
if (!node.isObject()) {
// ignore no object
return Collections.emptySet();
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/networknt/schema/AllOfValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNo
}

protected Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation, boolean walk) {
debug(logger, node, rootNode, instanceLocation);
debug(logger, executionContext, node, rootNode, instanceLocation);

SetView<ValidationMessage> childSchemaErrors = null;

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/networknt/schema/AnyOfValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNo

protected Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
JsonNodePath instanceLocation, boolean walk) {
debug(logger, node, rootNode, instanceLocation);
debug(logger, executionContext, node, rootNode, instanceLocation);

if (this.validationContext.getConfig().isOpenAPI3StyleDiscriminators()) {
executionContext.enterDiscriminatorContext(new DiscriminatorContext(), instanceLocation);
Expand Down
19 changes: 17 additions & 2 deletions src/main/java/com/networknt/schema/BaseJsonValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,23 @@ protected static boolean equals(double n1, double n2) {
return Math.abs(n1 - n2) < 1e-12;
}

protected static void debug(Logger logger, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
logger.debug("validate( {}, {}, {})", node, rootNode, instanceLocation);
public static void debug(Logger logger, ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
JsonNodePath instanceLocation) {
//logger.debug("validate( {}, {}, {})", node, rootNode, instanceLocation);
// The below is equivalent to the above but as there are more than 2 arguments
// the var-arg method is used and an array needs to be allocated even if debug
// is not enabled
if (executionContext.getExecutionConfig().isDebugEnabled() && logger.isDebugEnabled()) {
StringBuilder builder = new StringBuilder();
builder.append("validate( ");
builder.append(node.toString());
builder.append(", ");
builder.append(rootNode.toString());
builder.append(", ");
builder.append(instanceLocation.toString());
builder.append(")");
logger.debug(builder.toString());
}
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/networknt/schema/ConstValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public ConstValidator(SchemaLocation schemaLocation, JsonNodePath evaluationPath
}

public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, node, rootNode, instanceLocation);
debug(logger, executionContext, node, rootNode, instanceLocation);

if (schemaNode.isNumber() && node.isNumber()) {
if (schemaNode.decimalValue().compareTo(node.decimalValue()) != 0) {
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/networknt/schema/ContainsValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public ContainsValidator(SchemaLocation schemaLocation, JsonNodePath evaluationP

@Override
public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, node, rootNode, instanceLocation);
debug(logger, executionContext, node, rootNode, instanceLocation);

// ignores non-arrays
Set<ValidationMessage> results = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ private boolean matches(String value) {
@Override
public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
JsonNodePath instanceLocation) {
debug(logger, node, rootNode, instanceLocation);
debug(logger, executionContext, node, rootNode, instanceLocation);

// Ignore non-strings
JsonType nodeType = TypeFactory.getValueNodeType(node, this.validationContext.getConfig());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ else if (!PATTERN.matcher(this.contentMediaType).matches()) {
@Override
public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
JsonNodePath instanceLocation) {
debug(logger, node, rootNode, instanceLocation);
debug(logger, executionContext, node, rootNode, instanceLocation);

// Ignore non-strings
JsonType nodeType = TypeFactory.getValueNodeType(node, this.validationContext.getConfig());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public DependenciesValidator(SchemaLocation schemaLocation, JsonNodePath evaluat
}

public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, node, rootNode, instanceLocation);
debug(logger, executionContext, node, rootNode, instanceLocation);

Set<ValidationMessage> errors = null;

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/networknt/schema/DependentRequired.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public DependentRequired(SchemaLocation schemaLocation, JsonNodePath evaluationP
}

public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, node, rootNode, instanceLocation);
debug(logger, executionContext, node, rootNode, instanceLocation);

Set<ValidationMessage> errors = new LinkedHashSet<ValidationMessage>();

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/networknt/schema/DependentSchemas.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNo

protected Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
JsonNodePath instanceLocation, boolean walk) {
debug(logger, node, rootNode, instanceLocation);
debug(logger, executionContext, node, rootNode, instanceLocation);

Set<ValidationMessage> errors = null;
for (Iterator<String> it = node.fieldNames(); it.hasNext(); ) {
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/networknt/schema/DynamicRefValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ private static String resolve(JsonSchema parentSchema, String refValue) {

@Override
public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, node, rootNode, instanceLocation);
debug(logger, executionContext, node, rootNode, instanceLocation);
JsonSchema refSchema = this.schema.getSchema();
if (refSchema == null) {
ValidationMessage validationMessage = message().type(ValidatorTypeCode.DYNAMIC_REF.getValue())
Expand All @@ -107,7 +107,7 @@ public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNo

@Override
public Set<ValidationMessage> walk(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation, boolean shouldValidateSchema) {
debug(logger, node, rootNode, instanceLocation);
debug(logger, executionContext, node, rootNode, instanceLocation);
// This is important because if we use same JsonSchemaFactory for creating multiple JSONSchema instances,
// these schemas will be cached along with config. We have to replace the config for cached $ref references
// with the latest config. Reset the config.
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/networknt/schema/EnumValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public EnumValidator(SchemaLocation schemaLocation, JsonNodePath evaluationPath,
}

public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, node, rootNode, instanceLocation);
debug(logger, executionContext, node, rootNode, instanceLocation);

if (node.isNumber()) {
node = processNumberNode(node);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ public String thresholdValue() {
}

public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, node, rootNode, instanceLocation);
debug(logger, executionContext, node, rootNode, instanceLocation);

if (!JsonNodeUtil.isNumber(node, validationContext.getConfig())) {
// maximum only applies to numbers
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ public String thresholdValue() {
}

public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, node, rootNode, instanceLocation);
debug(logger, executionContext, node, rootNode, instanceLocation);

if (!JsonNodeUtil.isNumber(node, this.validationContext.getConfig())) {
// minimum only applies to numbers
Expand Down
28 changes: 27 additions & 1 deletion src/main/java/com/networknt/schema/ExecutionConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,16 @@ public class ExecutionConfig {
* Determine if the validation execution can fail fast.
*/
private boolean failFast = false;


/**
* Determine if debugging features such that logging are switched on.
* <p>
* This is turned off by default. This is present because the library attempts
* to log debug logs at each validation node and the logger evaluation on
* whether the logger is turned on is impacting performance.
*/
private boolean debugEnabled = false;

/**
* Gets the locale to use for formatting messages.
*
Expand Down Expand Up @@ -180,4 +189,21 @@ public void setAnnotationCollectionFilter(Predicate<String> annotationCollection
"annotationCollectionFilter must not be null");
}

/**
* Gets if debugging features such as logging is switched on.
*
* @return true if debug is enabled
*/
public boolean isDebugEnabled() {
return debugEnabled;
}

/**
* Sets if debugging features such as logging is switched on.
*
* @param debugEnabled true to enable debug
*/
public void setDebugEnabled(boolean debugEnabled) {
this.debugEnabled = debugEnabled;
}
}
2 changes: 1 addition & 1 deletion src/main/java/com/networknt/schema/FalseValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public FalseValidator(SchemaLocation schemaLocation, JsonNodePath evaluationPath
}

public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, node, rootNode, instanceLocation);
debug(logger, executionContext, node, rootNode, instanceLocation);
// For the false validator, it is always not valid
return Collections.singleton(message().instanceNode(node).instanceLocation(instanceLocation)
.locale(executionContext.getExecutionConfig().getLocale())
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/networknt/schema/FormatValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ protected Object getAnnotationValue() {
}

public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, node, rootNode, instanceLocation);
debug(logger, executionContext, node, rootNode, instanceLocation);
/*
* Annotations must be collected even if the format is unknown according to the specification.
*/
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/networknt/schema/IfValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public IfValidator(SchemaLocation schemaLocation, JsonNodePath evaluationPath, J

@Override
public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, node, rootNode, instanceLocation);
debug(logger, executionContext, node, rootNode, instanceLocation);

boolean ifConditionPassed = false;

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/networknt/schema/ItemsValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public ItemsValidator(SchemaLocation schemaLocation, JsonNodePath evaluationPath

@Override
public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, node, rootNode, instanceLocation);
debug(logger, executionContext, node, rootNode, instanceLocation);

if (!node.isArray() && !this.validationContext.getConfig().isTypeLoose()) {
// ignores non-arrays
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public ItemsValidator202012(SchemaLocation schemaLocation, JsonNodePath evaluati
@Override
public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
JsonNodePath instanceLocation) {
debug(logger, node, rootNode, instanceLocation);
debug(logger, executionContext, node, rootNode, instanceLocation);

// ignores non-arrays
if (node.isArray()) {
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/networknt/schema/MaxItemsValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public MaxItemsValidator(SchemaLocation schemaLocation, JsonNodePath evaluationP
}

public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, node, rootNode, instanceLocation);
debug(logger, executionContext, node, rootNode, instanceLocation);

if (node.isArray()) {
if (node.size() > max) {
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/networknt/schema/MaxLengthValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public MaxLengthValidator(SchemaLocation schemaLocation, JsonNodePath evaluation
}

public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, node, rootNode, instanceLocation);
debug(logger, executionContext, node, rootNode, instanceLocation);

JsonType nodeType = TypeFactory.getValueNodeType(node, this.validationContext.getConfig());
if (nodeType != JsonType.STRING) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public MaxPropertiesValidator(SchemaLocation schemaLocation, JsonNodePath evalua
}

public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, node, rootNode, instanceLocation);
debug(logger, executionContext, node, rootNode, instanceLocation);

if (node.isObject()) {
if (node.size() > max) {
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/networknt/schema/MaximumValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ public String thresholdValue() {
}

public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, node, rootNode, instanceLocation);
debug(logger, executionContext, node, rootNode, instanceLocation);

if (!JsonNodeUtil.isNumber(node, this.validationContext.getConfig())) {
// maximum only applies to numbers
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/networknt/schema/MinItemsValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public MinItemsValidator(SchemaLocation schemaLocation, JsonNodePath evaluationP
}

public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, node, rootNode, instanceLocation);
debug(logger, executionContext, node, rootNode, instanceLocation);

if (node.isArray()) {
if (node.size() < min) {
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/networknt/schema/MinLengthValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public MinLengthValidator(SchemaLocation schemaLocation, JsonNodePath evaluation
}

public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, node, rootNode, instanceLocation);
debug(logger, executionContext, node, rootNode, instanceLocation);

JsonType nodeType = TypeFactory.getValueNodeType(node, this.validationContext.getConfig());
if (nodeType != JsonType.STRING) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public MinPropertiesValidator(SchemaLocation schemaLocation, JsonNodePath evalua
}

public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, node, rootNode, instanceLocation);
debug(logger, executionContext, node, rootNode, instanceLocation);

if (node.isObject()) {
if (node.size() < min) {
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/networknt/schema/MinimumValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ public String thresholdValue() {
}

public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, node, rootNode, instanceLocation);
debug(logger, executionContext, node, rootNode, instanceLocation);

if (!JsonNodeUtil.isNumber(node, this.validationContext.getConfig())) {
// minimum only applies to numbers
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public MultipleOfValidator(SchemaLocation schemaLocation, JsonNodePath evaluatio

public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
JsonNodePath instanceLocation) {
debug(logger, node, rootNode, instanceLocation);
debug(logger, executionContext, node, rootNode, instanceLocation);
if (this.divisor != null) {
BigDecimal dividend = getDividend(node);
if (dividend != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public NotAllowedValidator(SchemaLocation schemaLocation, JsonNodePath evaluatio
}

public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode, JsonNodePath instanceLocation) {
debug(logger, node, rootNode, instanceLocation);
debug(logger, executionContext, node, rootNode, instanceLocation);

Set<ValidationMessage> errors = null;

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/networknt/schema/NotValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNo
protected Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNode node, JsonNode rootNode,
JsonNodePath instanceLocation, boolean walk) {
Set<ValidationMessage> errors = null;
debug(logger, node, rootNode, instanceLocation);
debug(logger, executionContext, node, rootNode, instanceLocation);

// Save flag as nested schema evaluation shouldn't trigger fail fast
boolean failFast = executionContext.isFailFast();
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/networknt/schema/OneOfValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ protected Set<ValidationMessage> validate(ExecutionContext executionContext, Jso
JsonNodePath instanceLocation, boolean walk) {
Set<ValidationMessage> errors = null;

debug(logger, node, rootNode, instanceLocation);
debug(logger, executionContext, node, rootNode, instanceLocation);
int numberOfValidSchema = 0;
int index = 0;
SetView<ValidationMessage> childErrors = null;
Expand Down
Loading

0 comments on commit 028710e

Please sign in to comment.