-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement the Witchcraft Logging API Idea plugin (#309)
* Implement the Witchcraft Logging API Idea plugin * Add generated changelog entries * defensive check * depends on the platform Co-authored-by: svc-changelog <[email protected]>
- Loading branch information
1 parent
3380d2b
commit 644c5d3
Showing
39 changed files
with
2,295 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
type: feature | ||
feature: | ||
description: Implement the Witchcraft Logging API Idea plugin | ||
links: | ||
- https://github.com/palantir/witchcraft-api/pull/309 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,6 @@ | ||
com.palantir.conjure.java:* = 6.1.0 | ||
com.palantir.conjure:conjure = 4.16.1 | ||
org.immutables:* = 2.8.8 | ||
org.assertj:assertj-core = 3.20.2 | ||
org.junit.jupiter:* = 5.7.2 | ||
org.mockito:* = 3.11.2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
apply plugin: 'java-library' | ||
apply plugin: 'maven-publish' | ||
apply plugin: 'org.jetbrains.intellij' | ||
apply plugin: 'org.inferred.processors' | ||
apply plugin: 'com.palantir.external-publish-jar' | ||
|
||
sourceCompatibility = 11 | ||
|
||
dependencies { | ||
implementation project(':witchcraft-logging-api:witchcraft-logging-api-objects'), { | ||
exclude group: 'org.slf4j' | ||
} | ||
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310' | ||
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jdk8' | ||
|
||
annotationProcessor 'org.immutables:value' | ||
compileOnly 'org.immutables:value-annotations' | ||
|
||
testImplementation 'org.assertj:assertj-core' | ||
testImplementation 'org.junit.jupiter:junit-jupiter' | ||
testImplementation 'org.mockito:mockito-core' | ||
} | ||
|
||
versionRecommendations { | ||
excludeConfigurations 'idea' | ||
} | ||
|
||
versionsLock { | ||
// 'org.jetbrains.intellij' creates a dependency on *IntelliJ*, which GCV cannot resolve | ||
disableJavaPluginDefaults() | ||
} | ||
|
||
def minimumIntellijBuild = '211.7628.21' // 2021.1.3 | ||
intellij { | ||
pluginName = 'witchcraft-logging-idea' | ||
version = minimumIntellijBuild | ||
updateSinceUntilBuild = false | ||
} | ||
|
||
patchPluginXml { | ||
pluginDescription = "Renders Witchcraft logging api logs from structured data into human-readable text." | ||
version = project.version | ||
sinceBuild = minimumIntellijBuild | ||
} | ||
|
||
publishPlugin { | ||
token = System.env.JETBRAINS_PLUGIN_REPO_TOKEN | ||
} | ||
|
||
check.dependsOn buildPlugin, verifyPlugin | ||
tasks.publishPlugin.onlyIf { versionDetails().isCleanTag && System.env.JETBRAINS_PLUGIN_REPO_TOKEN != null } | ||
tasks.publish.dependsOn publishPlugin | ||
buildSearchableOptions.enabled = false | ||
// Prevent nebula.maven-publish from trying to publish components.java - we are publishing our own different artifact | ||
ext."nebulaPublish.maven.jar" = false | ||
publishing { | ||
publications { | ||
nebula(MavenPublication) { | ||
artifact buildPlugin | ||
} | ||
} | ||
} |
84 changes: 84 additions & 0 deletions
84
...ging-idea/src/main/java/com/palantir/witchcraft/logging/format/CombineWithLogVisitor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
/* | ||
* (c) Copyright 2021 Palantir Technologies Inc. All rights reserved. | ||
* | ||
* 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. | ||
*/ | ||
|
||
package com.palantir.witchcraft.logging.format; | ||
|
||
import com.palantir.witchcraft.api.logging.AuditLogV2; | ||
import com.palantir.witchcraft.api.logging.DiagnosticLogV1; | ||
import com.palantir.witchcraft.api.logging.EventLogV2; | ||
import com.palantir.witchcraft.api.logging.MetricLogV1; | ||
import com.palantir.witchcraft.api.logging.RequestLogV2; | ||
import com.palantir.witchcraft.api.logging.ServiceLogV1; | ||
import com.palantir.witchcraft.api.logging.TraceLogV1; | ||
import java.util.Optional; | ||
import java.util.function.BiFunction; | ||
|
||
final class CombineWithLogVisitor<T, U, R> implements LogVisitor<R> { | ||
private final LogVisitor<T> first; | ||
private final LogVisitor<U> second; | ||
private final BiFunction<T, U, R> combiner; | ||
|
||
CombineWithLogVisitor(LogVisitor<T> first, LogVisitor<U> second, BiFunction<T, U, R> combiner) { | ||
this.first = first; | ||
this.second = second; | ||
this.combiner = combiner; | ||
} | ||
|
||
@Override | ||
public Optional<R> serviceV1(ServiceLogV1 serviceLogV1) { | ||
return combineWith(serviceLogV1, LogVisitor::serviceV1); | ||
} | ||
|
||
@Override | ||
public Optional<R> requestV2(RequestLogV2 requestLogV2) { | ||
return combineWith(requestLogV2, LogVisitor::requestV2); | ||
} | ||
|
||
@Override | ||
public Optional<R> eventV2(EventLogV2 eventLogV2) { | ||
return combineWith(eventLogV2, LogVisitor::eventV2); | ||
} | ||
|
||
@Override | ||
public Optional<R> metricV1(MetricLogV1 metricLogV1) { | ||
return combineWith(metricLogV1, LogVisitor::metricV1); | ||
} | ||
|
||
@Override | ||
public Optional<R> traceV1(TraceLogV1 traceLogV1) { | ||
return combineWith(traceLogV1, LogVisitor::traceV1); | ||
} | ||
|
||
@Override | ||
public Optional<R> auditV2(AuditLogV2 auditLogV2) { | ||
return combineWith(auditLogV2, LogVisitor::auditV2); | ||
} | ||
|
||
@Override | ||
public Optional<R> diagnosticV1(DiagnosticLogV1 diagnosticLogV1) { | ||
return combineWith(diagnosticLogV1, LogVisitor::diagnosticV1); | ||
} | ||
|
||
private <L> Optional<R> combineWith(L log, LogFunctionSelector<L> logFunc) { | ||
return logFunc.apply(first, log).flatMap(t -> { | ||
return logFunc.apply(second, log).map(u -> combiner.apply(t, u)); | ||
}); | ||
} | ||
|
||
private interface LogFunctionSelector<L> { | ||
<X> Optional<X> apply(LogVisitor<X> logVisitor, L logLine); | ||
} | ||
} |
39 changes: 39 additions & 0 deletions
39
...-logging-idea/src/main/java/com/palantir/witchcraft/logging/format/EventLogFormatter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/* | ||
* (c) Copyright 2021 Palantir Technologies Inc. All rights reserved. | ||
* | ||
* 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. | ||
*/ | ||
|
||
package com.palantir.witchcraft.logging.format; | ||
|
||
import com.palantir.witchcraft.api.logging.EventLogV2; | ||
import java.time.format.DateTimeFormatter; | ||
|
||
final class EventLogFormatter { | ||
private EventLogFormatter() {} | ||
|
||
static String format(EventLogV2 event) { | ||
StringBuilder buffer = new StringBuilder().append('['); | ||
DateTimeFormatter.ISO_INSTANT.formatTo(event.getTime(), buffer); | ||
buffer.append("] ").append(event.getEventName()); | ||
if (!event.getValues().isEmpty()) { | ||
buffer.append(' '); | ||
Formatting.niceMap(event.getValues(), buffer); | ||
} | ||
if (!event.getUnsafeParams().isEmpty()) { | ||
buffer.append(' '); | ||
Formatting.niceMap(event.getUnsafeParams(), buffer); | ||
} | ||
return buffer.toString(); | ||
} | ||
} |
72 changes: 72 additions & 0 deletions
72
witchcraft-logging-idea/src/main/java/com/palantir/witchcraft/logging/format/Formatting.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
/* | ||
* (c) Copyright 2021 Palantir Technologies Inc. All rights reserved. | ||
* | ||
* 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. | ||
*/ | ||
|
||
package com.palantir.witchcraft.logging.format; | ||
|
||
import com.google.common.base.CharMatcher; | ||
import java.util.Map; | ||
import java.util.function.Consumer; | ||
|
||
/** Utility functionality shared between {@link LogFormatter} implementations. */ | ||
final class Formatting { | ||
|
||
static final CharMatcher NEWLINE_MATCHER = CharMatcher.is('\n'); | ||
|
||
private static final ThreadLocal<StringBuilder> REUSABLE_STRING_BUILDER = | ||
ThreadLocal.withInitial(() -> new StringBuilder(1024)); | ||
|
||
static void niceMap(Map<String, ?> params, StringBuilder sb) { | ||
sb.append('('); | ||
formatParamsTo(params, sb); | ||
if (!params.isEmpty()) { | ||
sb.setLength(sb.length() - 2); | ||
} | ||
sb.append(')'); | ||
} | ||
|
||
static void formatParamsTo(Map<String, ?> params, StringBuilder sb) { | ||
for (Map.Entry<String, ?> entry : params.entrySet()) { | ||
String key = entry.getKey(); | ||
Object value = entry.getValue(); | ||
sb.append(key).append(": ").append(safeString(value)).append(", "); | ||
} | ||
} | ||
|
||
static String safeString(Object value) { | ||
try { | ||
return String.valueOf(value); | ||
} catch (RuntimeException e) { | ||
// Fallback if toString throws | ||
return value.getClass().getSimpleName() + '@' + System.identityHashCode(value); | ||
} | ||
} | ||
|
||
static String withStringBuilder(Consumer<StringBuilder> function) { | ||
StringBuilder builder = REUSABLE_STRING_BUILDER.get(); | ||
builder.setLength(0); | ||
function.accept(builder); | ||
String result = builder.toString(); | ||
if (builder.length() > 1024 * 16) { | ||
// Buffer has grown too large, allow the instance to be collected | ||
REUSABLE_STRING_BUILDER.remove(); | ||
} else { | ||
builder.setLength(0); | ||
} | ||
return result; | ||
} | ||
|
||
private Formatting() {} | ||
} |
53 changes: 53 additions & 0 deletions
53
...craft-logging-idea/src/main/java/com/palantir/witchcraft/logging/format/LogFormatter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
/* | ||
* (c) Copyright 2021 Palantir Technologies Inc. All rights reserved. | ||
* | ||
* 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. | ||
*/ | ||
|
||
package com.palantir.witchcraft.logging.format; | ||
|
||
import com.palantir.witchcraft.api.logging.EventLogV2; | ||
import com.palantir.witchcraft.api.logging.MetricLogV1; | ||
import com.palantir.witchcraft.api.logging.RequestLogV2; | ||
import com.palantir.witchcraft.api.logging.ServiceLogV1; | ||
import com.palantir.witchcraft.api.logging.TraceLogV1; | ||
import java.util.Optional; | ||
|
||
public enum LogFormatter implements LogVisitor<String> { | ||
INSTANCE; | ||
|
||
@Override | ||
public Optional<String> serviceV1(ServiceLogV1 serviceLogV1) { | ||
return Optional.of(ServiceLogFormatter.format(serviceLogV1)); | ||
} | ||
|
||
@Override | ||
public Optional<String> requestV2(RequestLogV2 requestLogV2) { | ||
return Optional.of(RequestLogFormatter.format(requestLogV2)); | ||
} | ||
|
||
@Override | ||
public Optional<String> eventV2(EventLogV2 eventLogV2) { | ||
return Optional.of(EventLogFormatter.format(eventLogV2)); | ||
} | ||
|
||
@Override | ||
public Optional<String> metricV1(MetricLogV1 metricLogV1) { | ||
return Optional.of(MetricLogFormatter.format(metricLogV1)); | ||
} | ||
|
||
@Override | ||
public Optional<String> traceV1(TraceLogV1 traceLogV1) { | ||
return Optional.of(TraceLogFormatter.format(traceLogV1)); | ||
} | ||
} |
Oops, something went wrong.