8215175: Inconsistencies in JFR event metadata
Reviewed-by: mgronlun
This commit is contained in:
parent
169729fe9b
commit
a3ca6f482e
@ -185,7 +185,7 @@ static int array_size(const oop object) {
|
||||
if (object->is_array()) {
|
||||
return arrayOop(object)->length();
|
||||
}
|
||||
return -1;
|
||||
return min_jint;
|
||||
}
|
||||
|
||||
void EmitEventOperation::write_event(const ObjectSample* sample, EdgeStore* edge_store) {
|
||||
|
@ -65,19 +65,19 @@
|
||||
<Field type="InflateCause" name="cause" label="Monitor Inflation Cause" description="Cause of inflation" />
|
||||
</Event>
|
||||
|
||||
<Event name="BiasedLockRevocation" category="Java Application" label="Biased Lock Revocation" description="Revoked bias of object" thread="true"
|
||||
<Event name="BiasedLockRevocation" category="Java Virtual Machine, Runtime" label="Biased Lock Revocation" description="Revoked bias of object" thread="true"
|
||||
stackTrace="true">
|
||||
<Field type="Class" name="lockClass" label="Lock Class" description="Class of object whose biased lock was revoked" />
|
||||
<Field type="ulong" name="safepointId" label="Safepoint Identifier" relation="SafepointId" />
|
||||
<Field type="Thread" name="previousOwner" label="Previous Owner" description="Thread owning the bias before revocation" />
|
||||
</Event>
|
||||
|
||||
<Event name="BiasedLockSelfRevocation" category="Java Application" label="Biased Lock Self Revocation" description="Revoked bias of object biased towards own thread"
|
||||
<Event name="BiasedLockSelfRevocation" category="Java Virtual Machine, Runtime" label="Biased Lock Self Revocation" description="Revoked bias of object biased towards own thread"
|
||||
thread="true" stackTrace="true">
|
||||
<Field type="Class" name="lockClass" label="Lock Class" description="Class of object whose biased lock was revoked" />
|
||||
</Event>
|
||||
|
||||
<Event name="BiasedLockClassRevocation" category="Java Application" label="Biased Lock Class Revocation" description="Revoked biases for all instances of a class"
|
||||
<Event name="BiasedLockClassRevocation" category="Java Virtual Machine, Runtime" label="Biased Lock Class Revocation" description="Revoked biases for all instances of a class"
|
||||
thread="true" stackTrace="true">
|
||||
<Field type="Class" name="revokedClass" label="Revoked Class" description="Class whose biased locks were revoked" />
|
||||
<Field type="boolean" name="disableBiasing" label="Disable Further Biasing" description="Whether further biasing for instances of this class will be allowed" />
|
||||
@ -350,7 +350,7 @@
|
||||
<Field type="ulong" contentType="bytes" name="recentMutatorAllocationSize" label="Recent Mutator Allocation Size"
|
||||
description="Mutator allocation during mutator operation in the most recent interval" />
|
||||
<Field type="long" contentType="millis" name="recentMutatorDuration" label="Recent Mutator Duration" description="Time the mutator ran in the most recent interval" />
|
||||
<Field type="double" name="recentAllocationRate" label="Recent Allocation Rate" description="Allocation rate of the mutator in the most recent interval in bytes/second" />
|
||||
<Field type="double" contentType="bytes-per-second" name="recentAllocationRate" label="Recent Allocation Rate" description="Allocation rate of the mutator in the most recent interval in bytes/second" />
|
||||
<Field type="long" contentType="millis" name="lastMarkingDuration" label="Last Marking Duration" description="Last time from the end of the last initial mark to the first mixed GC" />
|
||||
</Event>
|
||||
|
||||
@ -362,7 +362,7 @@
|
||||
<Field type="ulong" contentType="bytes" name="ihopTargetOccupancy" label="IHOP Target Occupancy" description="Internal target old generation occupancy to reach at the start of mixed GC" />
|
||||
<Field type="ulong" contentType="bytes" name="currentOccupancy" label="Current Occupancy" description="Current old generation occupancy" />
|
||||
<Field type="ulong" contentType="bytes" name="additionalBufferSize" label="Additional Buffer" description="Additional buffer size" experimental="true" />
|
||||
<Field type="double" name="predictedAllocationRate" label="Predicted Allocation Rate" description="Current predicted allocation rate for the mutator in bytes/second" />
|
||||
<Field type="double" contentType="bytes-per-second" name="predictedAllocationRate" label="Predicted Allocation Rate" description="Current predicted allocation rate for the mutator in bytes/second" />
|
||||
<Field type="long" contentType="millis" name="predictedMarkingDuration" label="Predicted Marking Duration"
|
||||
description="Current predicted time from the end of the last initial mark to the first mixed GC" />
|
||||
<Field type="boolean" name="predictionActive" label="Prediction Active" description="Indicates whether the adaptive IHOP prediction is active" />
|
||||
@ -564,9 +564,9 @@
|
||||
relation="SafepointId" />
|
||||
</Event>
|
||||
|
||||
<Event name="Shutdown" category="Java Virtual Machine, Runtime" label="VM Shutdown" description="VM shutting down" thread="true" stackTrace="true"
|
||||
<Event name="Shutdown" category="Java Virtual Machine, Runtime" label="JVM Shutdown" description="JVM shutting down" thread="true" stackTrace="true"
|
||||
startTime="false">
|
||||
<Field type="string" name="reason" label="Reason" description="Reason for VM shutdown" />
|
||||
<Field type="string" name="reason" label="Reason" description="Reason for JVM shutdown" />
|
||||
</Event>
|
||||
|
||||
<Event name="ObjectAllocationInNewTLAB" category="Java Application" label="Allocation in new TLAB" description="Allocation in new Thread Local Allocation Buffer"
|
||||
@ -582,7 +582,7 @@
|
||||
<Field type="ulong" contentType="bytes" name="allocationSize" label="Allocation Size" />
|
||||
</Event>
|
||||
|
||||
<Event name="OldObjectSample" category="Java Application" label="Old Object Sample" description="A potential memory leak" stackTrace="true" thread="true"
|
||||
<Event name="OldObjectSample" category="Java Virtual Machine, Profiling" label="Old Object Sample" description="A potential memory leak" stackTrace="true" thread="true"
|
||||
startTime="false" cutoff="true">
|
||||
<Field type="Ticks" name="allocationTime" label="Allocation Time" />
|
||||
<Field type="ulong" contentType="bytes" name="lastKnownHeapUsage" label="Last Known Heap Usage" />
|
||||
@ -647,8 +647,8 @@
|
||||
<Event name="CPUTimeStampCounter" category="Operating System, Processor" label="CPU Time Stamp Counter" period="endChunk">
|
||||
<Field type="boolean" name="fastTimeEnabled" label="Fast Time" />
|
||||
<Field type="boolean" name="fastTimeAutoEnabled" label="Trusted Platform" />
|
||||
<Field type="long" name="osFrequency" label="OS Frequency Per Second" />
|
||||
<Field type="long" name="fastTimeFrequency" label="Fast Time Frequency per Second" />
|
||||
<Field type="long" contentType="hertz" name="osFrequency" label="OS Frequency" />
|
||||
<Field type="long" contentType="hertz" name="fastTimeFrequency" label="Fast Time Frequency" />
|
||||
</Event>
|
||||
|
||||
<Event name="CPULoad" category="Operating System, Processor" label="CPU Load" description="OS CPU Load" period="everyChunk">
|
||||
@ -663,13 +663,13 @@
|
||||
</Event>
|
||||
|
||||
<Event name="ThreadContextSwitchRate" category="Operating System, Processor" label="Thread Context Switch Rate" period="everyChunk">
|
||||
<Field type="float" name="switchRate" label="Switch Rate" description="Number of context switches per second" />
|
||||
<Field type="float" contentType="hertz" name="switchRate" label="Switch Rate" description="Number of context switches per second" />
|
||||
</Event>
|
||||
|
||||
<Event name="NetworkUtilization" category="Operating System, Network" label="Network Utilization" period="everyChunk">
|
||||
<Field type="NetworkInterfaceName" name="networkInterface" label="Network Interface" description="Network Interface Name"/>
|
||||
<Field type="long" contentType="bytes" name="readRate" label="Read Rate" description="Number of incoming bytes per second"/>
|
||||
<Field type="long" contentType="bytes" name="writeRate" label="Write Rate" description="Number of outgoing bytes per second"/>
|
||||
<Field type="long" contentType="bits-per-second" name="readRate" label="Read Rate" description="Number of incoming bits per second"/>
|
||||
<Field type="long" contentType="bits-per-second" name="writeRate" label="Write Rate" description="Number of outgoing bits per second"/>
|
||||
</Event>
|
||||
|
||||
<Event name="JavaThreadStatistics" category="Java Application, Statistics" label="Java Thread Statistics" period="everyChunk">
|
||||
@ -687,7 +687,7 @@
|
||||
<Event name="ClassLoaderStatistics" category="Java Application, Statistics" label="Class Loader Statistics" period="everyChunk">
|
||||
<Field type="ClassLoader" name="classLoader" label="Class Loader" />
|
||||
<Field type="ClassLoader" name="parentClassLoader" label="Parent Class Loader" />
|
||||
<Field type="ulong" contentType="address" name="classLoaderData" label="ClassLoaderData pointer" description="Pointer to the ClassLoaderData structure in the JVM" />
|
||||
<Field type="ulong" contentType="address" name="classLoaderData" label="ClassLoaderData Pointer" description="Pointer to the ClassLoaderData structure in the JVM" />
|
||||
<Field type="long" name="classCount" label="Classes" description="Number of loaded classes" />
|
||||
<Field type="ulong" contentType="bytes" name="chunkSize" label="Total Chunk Size" description="Total size of all allocated metaspace chunks (each chunk has several blocks)" />
|
||||
<Field type="ulong" contentType="bytes" name="blockSize" label="Total Block Size" description="Total size of all allocated metaspace blocks (each chunk has several blocks)" />
|
||||
@ -741,8 +741,7 @@
|
||||
<Event name="ModuleExport" category="Java Virtual Machine, Runtime, Modules" label="Module Export" thread="false" period="everyChunk">
|
||||
<Field type="Package" name="exportedPackage" label="Exported Package" />
|
||||
<Field type="Module" name="targetModule" label="Target Module"
|
||||
description="Module to which the package is qualifiedly exported.
|
||||
If null, the package is unqualifiedly exported" />
|
||||
description="Module to which the package is qualifiedly exported. If null or N/A, the package is unqualifiedly exported" />
|
||||
</Event>
|
||||
|
||||
<Event name="CompilerStatistics" category="Java Virtual Machine, Compiler" label="Compiler Statistics" thread="false" period="everyChunk" startTime="false">
|
||||
@ -1096,7 +1095,7 @@
|
||||
<Field type="OldObjectArray" name="array" label="Array Information" description="Array or null if it is not an array" />
|
||||
<Field type="OldObjectField" name="field" label="Field Information" description="Field or null if it is an array" />
|
||||
<Field type="OldObject" name="object" label="Object" description="Object holder for this reference" />
|
||||
<Field type="int" name="skip" label="Skip value" description="The object is this many hops away" />
|
||||
<Field type="int" name="skip" label="Skip Value" description="The object is this many hops away" />
|
||||
</Type>
|
||||
|
||||
<Type name="StackFrame">
|
||||
@ -1134,13 +1133,16 @@
|
||||
<XmlType name="char" javaType="char" parameterType="char" fieldType="char"/>
|
||||
<XmlType name="string" javaType="java.lang.String" parameterType="const char*" fieldType="const char*"/>
|
||||
|
||||
<XmlContentType name="bytes" annotationType="jdk.jfr.DataAmount" annotationValue="BYTES" />
|
||||
<XmlContentType name="tickstamp" annotationType="jdk.jfr.Timestamp" annotationValue="TICKS" />
|
||||
<XmlContentType name="epochmillis" annotationType="jdk.jfr.Timestamp" annotationValue="MILLISECONDS_SINCE_EPOCH" />
|
||||
<XmlContentType name="tickspan" annotationType="jdk.jfr.Timespan" annotationValue="TICKS" />
|
||||
<XmlContentType name="address" annotationType="jdk.jfr.MemoryAddress" />
|
||||
<XmlContentType name="percentage" annotationType="jdk.jfr.Percentage" />
|
||||
<XmlContentType name="millis" annotationType="jdk.jfr.Timespan" annotationValue="MILLISECONDS" />
|
||||
<XmlContentType name="nanos" annotationType="jdk.jfr.Timespan" annotationValue="NANOSECONDS" />
|
||||
|
||||
<XmlContentType name="bytes" annotation="jdk.jfr.DataAmount(BYTES)" />
|
||||
<XmlContentType name="tickstamp" annotation="jdk.jfr.Timestamp(TICKS)" />
|
||||
<XmlContentType name="epochmillis" annotation="jdk.jfr.Timestamp(MILLISECONDS_SINCE_EPOCH)" />
|
||||
<XmlContentType name="tickspan" annotation="jdk.jfr.Timespan(TICKS)" />
|
||||
<XmlContentType name="address" annotation="jdk.jfr.MemoryAddress" />
|
||||
<XmlContentType name="percentage" annotation="jdk.jfr.Percentage" />
|
||||
<XmlContentType name="millis" annotation="jdk.jfr.Timespan(MILLISECONDS)" />
|
||||
<XmlContentType name="nanos" annotation="jdk.jfr.Timespan(NANOSECONDS)" />
|
||||
<XmlContentType name="hertz" annotation="jdk.jfr.Frequency" />
|
||||
<XmlContentType name="bytes-per-second" annotation="jdk.jfr.DataAmount(BYTES), jdk.jfr.Frequency" />
|
||||
<XmlContentType name="bits-per-second" annotation="jdk.jfr.DataAmount(BITS), jdk.jfr.Frequency" />
|
||||
|
||||
</Metadata>
|
||||
|
@ -107,8 +107,7 @@
|
||||
<xs:element name="XmlContentType">
|
||||
<xs:complexType>
|
||||
<xs:attribute name="name" type="xs:NMTOKEN" use="required" />
|
||||
<xs:attribute name="annotationType" type="xs:NMTOKEN" use="required" />
|
||||
<xs:attribute name="annotationValue" type="xs:string" use="optional" />
|
||||
<xs:attribute name="annotation" type="xs:string" use="required" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="Relation">
|
||||
|
@ -174,8 +174,8 @@ void JfrNetworkUtilization::send_events() {
|
||||
event.set_starttime(cur_time);
|
||||
event.set_endtime(cur_time);
|
||||
event.set_networkInterface(entry.id);
|
||||
event.set_readRate(read_rate);
|
||||
event.set_writeRate(write_rate);
|
||||
event.set_readRate(8 * read_rate);
|
||||
event.set_writeRate(8 * write_rate);
|
||||
event.commit();
|
||||
}
|
||||
// update existing entry with new values
|
||||
|
@ -100,7 +100,7 @@ final class MetadataHandler extends DefaultHandler implements EntityResolver {
|
||||
|
||||
final Map<String, TypeElement> types = new LinkedHashMap<>(200);
|
||||
final Map<String, XmlType> xmlTypes = new HashMap<>(20);
|
||||
final Map<String, AnnotationElement> xmlContentTypes = new HashMap<>(20);
|
||||
final Map<String, List<AnnotationElement>> xmlContentTypes = new HashMap<>(20);
|
||||
final List<String> relations = new ArrayList<>();
|
||||
long eventTypeId = 255;
|
||||
long structTypeId = 33;
|
||||
@ -148,11 +148,8 @@ final class MetadataHandler extends DefaultHandler implements EntityResolver {
|
||||
break;
|
||||
case "XmlContentType":
|
||||
String name = attributes.getValue("name");
|
||||
String type = attributes.getValue("annotationType");
|
||||
String value = attributes.getValue("annotationValue");
|
||||
Class<? extends Annotation> annotationType = createAnnotationClass(type);
|
||||
AnnotationElement ae = value == null ? new AnnotationElement(annotationType) : new AnnotationElement(annotationType, value);
|
||||
xmlContentTypes.put(name, ae);
|
||||
String annotation = attributes.getValue("annotation");
|
||||
xmlContentTypes.put(name, createAnnotationElements(annotation));
|
||||
break;
|
||||
case "Relation":
|
||||
String n = attributes.getValue("name");
|
||||
@ -161,6 +158,27 @@ final class MetadataHandler extends DefaultHandler implements EntityResolver {
|
||||
}
|
||||
}
|
||||
|
||||
private List<AnnotationElement> createAnnotationElements(String annotation) throws InternalError {
|
||||
String[] annotations = annotation.split(",");
|
||||
List<AnnotationElement> annotationElements = new ArrayList<>();
|
||||
for (String a : annotations) {
|
||||
a = a.trim();
|
||||
int leftParenthesis = a.indexOf("(");
|
||||
if (leftParenthesis == -1) {
|
||||
annotationElements.add(new AnnotationElement(createAnnotationClass(a)));
|
||||
} else {
|
||||
int rightParenthesis = a.lastIndexOf(")");
|
||||
if (rightParenthesis == -1) {
|
||||
throw new InternalError("Expected closing parenthesis for 'XMLContentType'");
|
||||
}
|
||||
String value = a.substring(leftParenthesis + 1, rightParenthesis);
|
||||
String type = a.substring(0, leftParenthesis);
|
||||
annotationElements.add(new AnnotationElement(createAnnotationClass(type), value));
|
||||
}
|
||||
}
|
||||
return annotationElements;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Class<? extends Annotation> createAnnotationClass(String type) {
|
||||
try {
|
||||
@ -255,7 +273,7 @@ final class MetadataHandler extends DefaultHandler implements EntityResolver {
|
||||
aes.add(new AnnotationElement(Unsigned.class));
|
||||
}
|
||||
if (f.contentType != null) {
|
||||
aes.add(Objects.requireNonNull(xmlContentTypes.get(f.contentType)));
|
||||
aes.addAll(Objects.requireNonNull(xmlContentTypes.get(f.contentType)));
|
||||
}
|
||||
if (f.relation != null) {
|
||||
aes.add(Objects.requireNonNull(relationMap.get(f.relation)));
|
||||
|
@ -123,7 +123,7 @@ public final class PlatformRecording implements AutoCloseable {
|
||||
options.add("maxage=" + Utils.formatTimespan(maxAge, ""));
|
||||
}
|
||||
if (maxSize != 0) {
|
||||
options.add("maxsize=" + Utils.formatBytes(maxSize, ""));
|
||||
options.add("maxsize=" + Utils.formatBytesCompact(maxSize));
|
||||
}
|
||||
if (dumpOnExit) {
|
||||
options.add("dumponexit=true");
|
||||
|
@ -103,18 +103,53 @@ public final class Utils {
|
||||
}
|
||||
}
|
||||
|
||||
public static String formatBytes(long bytes, String separation) {
|
||||
if (bytes == 1) {
|
||||
return "1 byte";
|
||||
}
|
||||
if (bytes < 1024) {
|
||||
return bytes + " bytes";
|
||||
}
|
||||
int exp = (int) (Math.log(bytes) / Math.log(1024));
|
||||
char bytePrefix = "kMGTPE".charAt(exp - 1);
|
||||
return String.format("%.1f%s%cB", bytes / Math.pow(1024, exp), separation, bytePrefix);
|
||||
// Tjis method can't handle Long.MIN_VALUE because absolute value is negative
|
||||
private static String formatDataAmount(String formatter, long amount) {
|
||||
int exp = (int) (Math.log(Math.abs(amount)) / Math.log(1024));
|
||||
char unitPrefix = "kMGTPE".charAt(exp - 1);
|
||||
return String.format(formatter, amount / Math.pow(1024, exp), unitPrefix);
|
||||
}
|
||||
|
||||
public static String formatBytesCompact(long bytes) {
|
||||
if (bytes < 1024) {
|
||||
return String.valueOf(bytes);
|
||||
}
|
||||
return formatDataAmount("%.1f%cB", bytes);
|
||||
}
|
||||
|
||||
public static String formatBits(long bits) {
|
||||
if (bits == 1 || bits == -1) {
|
||||
return bits + " bit";
|
||||
}
|
||||
if (bits < 1024 && bits > -1024) {
|
||||
return bits + " bits";
|
||||
}
|
||||
return formatDataAmount("%.1f %cbit", bits);
|
||||
}
|
||||
|
||||
public static String formatBytes(long bytes) {
|
||||
if (bytes == 1 || bytes == -1) {
|
||||
return bytes + " byte";
|
||||
}
|
||||
if (bytes < 1024 && bytes > -1024) {
|
||||
return bytes + " bytes";
|
||||
}
|
||||
return formatDataAmount("%.1f %cB", bytes);
|
||||
}
|
||||
|
||||
public static String formatBytesPerSecond(long bytes) {
|
||||
if (bytes < 1024 && bytes > -1024) {
|
||||
return bytes + " byte/s";
|
||||
}
|
||||
return formatDataAmount("%.1f %cB/s", bytes);
|
||||
}
|
||||
|
||||
public static String formatBitsPerSecond(long bits) {
|
||||
if (bits < 1024 && bits > -1024) {
|
||||
return bits + " bps";
|
||||
}
|
||||
return formatDataAmount("%.1f %cbps", bits);
|
||||
}
|
||||
public static String formatTimespan(Duration dValue, String separation) {
|
||||
if (dValue == null) {
|
||||
return "0";
|
||||
|
@ -109,7 +109,7 @@ abstract class AbstractDCmd {
|
||||
try {
|
||||
print(" ");
|
||||
long bytes = SecuritySupport.getFileSize(file);
|
||||
printBytes(bytes, " ");
|
||||
printBytes(bytes);
|
||||
} catch (IOException e) {
|
||||
// Ignore, not essential
|
||||
}
|
||||
@ -152,8 +152,8 @@ abstract class AbstractDCmd {
|
||||
println();
|
||||
}
|
||||
|
||||
protected final void printBytes(long bytes, String separation) {
|
||||
print(Utils.formatBytes(bytes, separation));
|
||||
protected final void printBytes(long bytes) {
|
||||
print(Utils.formatBytes(bytes));
|
||||
}
|
||||
|
||||
protected final void printTimespan(Duration timespan, String separator) {
|
||||
|
@ -39,6 +39,7 @@ import jdk.jfr.SettingDescriptor;
|
||||
import jdk.jfr.internal.LogLevel;
|
||||
import jdk.jfr.internal.LogTag;
|
||||
import jdk.jfr.internal.Logger;
|
||||
import jdk.jfr.internal.Utils;
|
||||
|
||||
/**
|
||||
* JFR.check - invoked from native
|
||||
@ -117,7 +118,7 @@ final class DCmdCheck extends AbstractDCmd {
|
||||
long maxSize = recording.getMaxSize();
|
||||
if (maxSize != 0) {
|
||||
print(" maxsize=");
|
||||
printBytes(maxSize, "");
|
||||
print(Utils.formatBytesCompact(maxSize));
|
||||
}
|
||||
Duration maxAge = recording.getMaxAge();
|
||||
if (maxAge != null) {
|
||||
|
@ -193,25 +193,25 @@ final class DCmdConfigure extends AbstractDCmd {
|
||||
|
||||
private void printGlobalBufferSize() {
|
||||
print("Global buffer size: ");
|
||||
printBytes(Options.getGlobalBufferSize(), " ");
|
||||
printBytes(Options.getGlobalBufferSize());
|
||||
println();
|
||||
}
|
||||
|
||||
private void printThreadBufferSize() {
|
||||
print("Thread buffer size: ");
|
||||
printBytes(Options.getThreadBufferSize(), " ");
|
||||
printBytes(Options.getThreadBufferSize());
|
||||
println();
|
||||
}
|
||||
|
||||
private void printMemorySize() {
|
||||
print("Memory size: ");
|
||||
printBytes(Options.getMemorySize(), " ");
|
||||
printBytes(Options.getMemorySize());
|
||||
println();
|
||||
}
|
||||
|
||||
private void printMaxChunkSize() {
|
||||
print("Max chunk size: ");
|
||||
printBytes(Options.getMaxChunkSize(), " ");
|
||||
printBytes(Options.getMaxChunkSize());
|
||||
println();
|
||||
}
|
||||
}
|
||||
|
@ -315,11 +315,7 @@ public final class PrettyWriter extends EventPrintWriter {
|
||||
printArray((Object[]) value);
|
||||
return;
|
||||
}
|
||||
if (field.getContentType() != null) {
|
||||
if (printFormatted(field, value)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (value instanceof Double) {
|
||||
Double d = (Double) value;
|
||||
if (Double.isNaN(d) || d == Double.NEGATIVE_INFINITY) {
|
||||
@ -349,6 +345,12 @@ public final class PrettyWriter extends EventPrintWriter {
|
||||
}
|
||||
}
|
||||
|
||||
if (field.getContentType() != null) {
|
||||
if (printFormatted(field, value)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
String text = String.valueOf(value);
|
||||
if (value instanceof String) {
|
||||
text = "\"" + text + "\"";
|
||||
@ -472,7 +474,7 @@ public final class PrettyWriter extends EventPrintWriter {
|
||||
private boolean printFormatted(ValueDescriptor field, Object value) {
|
||||
if (value instanceof Duration) {
|
||||
Duration d = (Duration) value;
|
||||
if (d.getSeconds() == Long.MIN_VALUE) {
|
||||
if (d.getSeconds() == Long.MIN_VALUE && d.getNano() == 0) {
|
||||
println("N/A");
|
||||
return true;
|
||||
}
|
||||
@ -513,12 +515,26 @@ public final class PrettyWriter extends EventPrintWriter {
|
||||
if (dataAmount != null) {
|
||||
if (value instanceof Number) {
|
||||
Number n = (Number) value;
|
||||
String bytes = Utils.formatBytes(n.longValue(), " ");
|
||||
long amount = n.longValue();
|
||||
if (field.getAnnotation(Frequency.class) != null) {
|
||||
bytes += "/s";
|
||||
if (dataAmount.value().equals(DataAmount.BYTES)) {
|
||||
println(Utils.formatBytesPerSecond(amount));
|
||||
return true;
|
||||
}
|
||||
if (dataAmount.value().equals(DataAmount.BITS)) {
|
||||
println(Utils.formatBitsPerSecond(amount));
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (dataAmount.value().equals(DataAmount.BYTES)) {
|
||||
println(Utils.formatBytes(amount));
|
||||
return true;
|
||||
}
|
||||
if (dataAmount.value().equals(DataAmount.BITS)) {
|
||||
println(Utils.formatBits(amount));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
println(bytes);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
MemoryAddress memoryAddress = field.getAnnotation(MemoryAddress.class);
|
||||
@ -529,6 +545,14 @@ public final class PrettyWriter extends EventPrintWriter {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Frequency frequency = field.getAnnotation(Frequency.class);
|
||||
if (frequency != null) {
|
||||
if (value instanceof Number) {
|
||||
println(value + " Hz");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package jdk.jfr.api.metadata.annotations;
|
||||
|
||||
import jdk.jfr.DataAmount;
|
||||
import jdk.jfr.Event;
|
||||
import jdk.jfr.Frequency;
|
||||
import jdk.jfr.Recording;
|
||||
import jdk.jfr.StackTrace;
|
||||
import jdk.jfr.consumer.RecordedEvent;
|
||||
import jdk.test.lib.Asserts;
|
||||
import jdk.test.lib.jfr.Events;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @key jfr
|
||||
* @summary Check that event values are properly formatted and sanity check
|
||||
* that extreme values don't throws exceptions
|
||||
* @requires vm.hasJFR
|
||||
* @library /test/lib
|
||||
* @run main/othervm jdk.jfr.api.metadata.annotations.TestFormatMissingValue
|
||||
*/
|
||||
public class TestFormatMissingValue {
|
||||
|
||||
@StackTrace(false)
|
||||
static class MultiContentTypeEvent extends Event {
|
||||
@DataAmount(DataAmount.BYTES)
|
||||
@Frequency
|
||||
long a = Long.MIN_VALUE;
|
||||
|
||||
@DataAmount(DataAmount.BYTES)
|
||||
@Frequency
|
||||
long b = Long.MAX_VALUE;
|
||||
|
||||
@DataAmount(DataAmount.BYTES)
|
||||
@Frequency
|
||||
int c = Integer.MIN_VALUE;
|
||||
|
||||
@DataAmount(DataAmount.BYTES)
|
||||
@Frequency
|
||||
int d = Integer.MAX_VALUE;
|
||||
|
||||
@DataAmount(DataAmount.BYTES)
|
||||
@Frequency
|
||||
double e = Double.NEGATIVE_INFINITY;
|
||||
|
||||
@DataAmount(DataAmount.BYTES)
|
||||
@Frequency
|
||||
double f = Double.POSITIVE_INFINITY;
|
||||
|
||||
@DataAmount(DataAmount.BYTES)
|
||||
@Frequency
|
||||
double g = Double.NaN;
|
||||
|
||||
@DataAmount(DataAmount.BYTES)
|
||||
@Frequency
|
||||
float h = Float.NEGATIVE_INFINITY;
|
||||
|
||||
@DataAmount(DataAmount.BYTES)
|
||||
@Frequency
|
||||
float i = Float.POSITIVE_INFINITY;
|
||||
|
||||
@DataAmount(DataAmount.BYTES)
|
||||
@Frequency
|
||||
float j = Float.NaN;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
try (Recording r = new Recording()) {
|
||||
r.start();
|
||||
MultiContentTypeEvent m = new MultiContentTypeEvent();
|
||||
m.commit();
|
||||
r.stop();
|
||||
for (RecordedEvent e : Events.fromRecording(r)) {
|
||||
String t = e.toString();
|
||||
assertContains(t, "a = N/A");
|
||||
assertContains(t, "c = N/A");
|
||||
assertContains(t, "e = N/A");
|
||||
assertContains(t, "g = N/A");
|
||||
assertContains(t, "h = N/A");
|
||||
assertContains(t, "j = N/A");
|
||||
|
||||
assertNotContains(t, "b = N/A");
|
||||
assertNotContains(t, "d = N/A");
|
||||
assertNotContains(t, "f = N/A");
|
||||
assertNotContains(t, "i = N/A");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void assertContains(String t, String text) {
|
||||
if (!t.contains(text)) {
|
||||
Asserts.fail("Expected '" + t + "' to contain text '" + text + "'");
|
||||
}
|
||||
}
|
||||
|
||||
private static void assertNotContains(String t, String text) {
|
||||
if (t.contains(text)) {
|
||||
Asserts.fail("Found unexpected value '" + text + "' in text '" + t + "'");
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user