Package io.perfmark

Class PerfMark


  • public final class PerfMark
    extends java.lang.Object
    PerfMark is a very low overhead tracing library. To use PerfMark, annotate the code that needs to be traced using the start and stop methods. For example:
    
     try (var close = PerfMark.traceTask("parseMessage")) {
       message = parse(bytes);
     }
     

    When PerfMark is enabled, these tracing calls will record the start and stop times of the given task. When disabled, PerfMark disables these tracing calls, resulting in no additional tracing overhead. PerfMark can be enabled or disabled using the setEnabled(boolean). By default, PerfMark starts off disabled. PerfMark can be automatically enabled by setting the System property io.perfmark.PerfMark.startEnabled to true.

    Tasks represent the span of work done by some code, starting and stopping in the same thread. Each task is started using one of the startTask methods, and ended using one of stopTask methods. Each start must have a corresponding stop. While not required, it is good practice for the start and stop calls have matching arguments for clarity. Tasks form a "tree", with each child task starting after the parent has started, and stopping before the parent has stopped. The most recently started (and not yet stopped) task is used by the tagging and linking commands described below.

    Tags are metadata about the task. Each Tag contains a String and/or a long that describes the task, such as an RPC name, or request ID. When PerfMark is disabled, the Tag objects are not created, avoiding overhead. Tags are useful for keeping track of metadata about a task(s) that doesn't change frequently, or needs to be applied at multiple layers. In addition to Tag objects, named-tags can be added to the current task using the attachTag methods. These allow including key-value like metadata with the task.

    Links allow the code to represent relationships between different threads. When one thread initiates work for another thread (such as a callback), Links express the control flow. For example:

    
     try (var close = PerfMark.traceTask("handleMessage")) {
       Link link = PerfMark.linkOut();
       var message = parse(bytes);
       executor.execute(() -> {
         try (var closeInner = PerfMark.traceTask("processMessage")) {
           PerfMark.linkIn(link);
           handle(message);
         }
       });
     }
     

    Links are created inside the scope of the current task and are linked into the scope of another task. PerfMark will represent the causal relationship between these two tasks. Links have a many-many relationship, and can be reused. Like Tasks and Tags, when PerfMark is disabled, the Links returned are no-op implementations.

    Events are a special kind of Task, which do not have a duration. In effect, they only have a single timestamp the represents a particular occurrence. Events are slightly more efficient than tasks while PerfMark is enabled, but cannot be used with Links or named-tags.

    • Field Summary

      Fields 
      Modifier and Type Field Description
      private static Impl impl  
    • Constructor Summary

      Constructors 
      Modifier Constructor Description
      private PerfMark()  
    • Method Summary

      All Methods Static Methods Concrete Methods Deprecated Methods 
      Modifier and Type Method Description
      static <T> void attachIntTag​(java.lang.String tagName, T tagObject, java.util.function.ToIntFunction<? super T> intFunction)
      Attaches an additional keyed tag to the current active task.
      static <T> void attachLongTag​(java.lang.String tagName, T tagObject, java.util.function.ToLongFunction<? super T> longFunction)
      Attaches an additional keyed tag to the current active task.
      static <T> void attachStringTag​(java.lang.String tagName, T tagObject, java.util.function.Function<? super T,​? extends java.lang.String> stringFunction)
      Attaches an additional keyed tag to the current active task.
      static void attachTag​(Tag tag)
      Attaches an additional tag to the current active task.
      static void attachTag​(java.lang.String tagName, long tagValue)
      Attaches an additional keyed tag to the current active task.
      static void attachTag​(java.lang.String tagName, long tagValue0, long tagValue1)
      Attaches an additional keyed tag to the current active task.
      static void attachTag​(java.lang.String tagName, java.lang.String tagValue)
      Attaches an additional keyed tag to the current active task.
      static <T> void attachTag​(java.lang.String tagName, T tagObject, StringFunction<? super T> stringFunction)
      Attaches an additional keyed tag to the current active task.
      static Tag createTag()
      Creates a tag with no name or numeric identifier.
      static Tag createTag​(long id)
      Creates a tag with no name.
      static Tag createTag​(java.lang.String name)
      Creates a tag with no numeric identifier.
      static Tag createTag​(java.lang.String name, long id)
      Creates a tag with both a name and a numeric identifier.
      static void event​(java.lang.String eventName)
      Marks an event.
      static void event​(java.lang.String eventName, Tag tag)
      Marks an event.
      static void event​(java.lang.String eventName, java.lang.String subEventName)
      Marks an event.
      static Link link()
      Deprecated.
      static void linkIn​(Link link)
      Associate this link with the most recently started task.
      static Link linkOut()
      A link connects between two tasks that start asynchronously.
      static boolean setEnabled​(boolean value)
      Turns on or off PerfMark recording.
      static void startTask​(java.lang.String taskName)
      Marks the beginning of a task.
      static void startTask​(java.lang.String taskName, Tag tag)
      Marks the beginning of a task.
      static void startTask​(java.lang.String taskName, java.lang.String subTaskName)
      Marks the beginning of a task.
      static <T> void startTask​(T taskNameObject, StringFunction<? super T> taskNameFunction)
      Marks the beginning of a task.
      static void stopTask()
      Marks the end of a task.
      static void stopTask​(java.lang.String taskName)
      Marks the end of a task.
      static void stopTask​(java.lang.String taskName, Tag tag)
      Marks the end of a task.
      static void stopTask​(java.lang.String taskName, java.lang.String subTaskName)
      Marks the end of a task.
      static TaskCloseable traceTask​(java.lang.String taskName)
      Marks the beginning of a task.
      static <T> TaskCloseable traceTask​(T taskNameObject, StringFunction<? super T> taskNameFunction)
      Marks the beginning of a task.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • impl

        private static final Impl impl
    • Constructor Detail

      • PerfMark

        private PerfMark()
    • Method Detail

      • setEnabled

        public static boolean setEnabled​(boolean value)
        Turns on or off PerfMark recording. Don't call this method too frequently; while neither on nor off have very high overhead, transitioning between the two may be slow.
        Parameters:
        value - true to enable PerfMark recording, or false to disable it.
        Returns:
        If the enabled value was changed.
        Since:
        0.13.37
      • startTask

        public static void startTask​(java.lang.String taskName,
                                     Tag tag)
        Marks the beginning of a task. If PerfMark is disabled, this method is a no-op. The name of the task should be a runtime-time constant, usually a string literal. Tasks with the same name can be grouped together for analysis later, so avoid using too many unique task names.

        The tag is a run-time identifier for the task. It represents the dynamic part of the task, while the task name is the constant part of the task. While not always enforced, tags should not be null.

        Parameters:
        taskName - the name of the task.
        tag - a user provided tag for the task.
        Since:
        0.13.37
      • startTask

        public static void startTask​(java.lang.String taskName)
        Marks the beginning of a task. If PerfMark is disabled, this method is a no-op. The name of the task should be a runtime-time constant, usually a string literal. Tasks with the same name can be grouped together for analysis later, so avoid using too many unique task names.
        Parameters:
        taskName - the name of the task.
        Since:
        0.13.37
      • startTask

        public static <T> void startTask​(T taskNameObject,
                                         StringFunction<? super T> taskNameFunction)
        Marks the beginning of a task. If PerfMark is disabled, this method is a no-op. The name of the task should be a runtime-time constant, usually a string literal. Tasks with the same name can be grouped together for analysis later, so avoid using too many unique task names.

        This function has many more caveats than the startTask(String) that accept a string. See the docs at attachTag(String, Object, StringFunction) for a list of risks associated with passing a function.

        Type Parameters:
        T - the object type to be stringified
        Parameters:
        taskNameObject - the name of the task.
        taskNameFunction - the function that will convert the taskNameObject to a taskName
        Since:
        0.22.0
      • startTask

        public static void startTask​(java.lang.String taskName,
                                     java.lang.String subTaskName)
        Marks the beginning of a task. If PerfMark is disabled, this method is a no-op. The names of the task and subtask should be runtime-time constants, usually a string literal. Tasks with the same name can be grouped together for analysis later, so avoid using too many unique task names.
        Parameters:
        taskName - the name of the task.
        subTaskName - the name of the sub task
        Since:
        0.20.0
      • traceTask

        @MustBeClosed
        @CheckReturnValue
        public static TaskCloseable traceTask​(java.lang.String taskName)
        Marks the beginning of a task. If PerfMark is disabled, this method is a no-op. The name of the task should be a runtime-time constant, usually a string literal. Tasks with the same name can be grouped together for analysis later, so avoid using too many unique task names.

        The returned closeable is meant to be used in a try-with-resources block. Callers should not allow the returned closeable to be used outside of the try block that initiated the call. Unlike other closeables, it is not safe to call close() more than once.

        Parameters:
        taskName - the name of the task.
        Returns:
        a closeable that must be closed at the end of the task
        Since:
        0.23.0
      • traceTask

        @MustBeClosed
        @CheckReturnValue
        public static <T> TaskCloseable traceTask​(T taskNameObject,
                                                  StringFunction<? super T> taskNameFunction)
        Marks the beginning of a task. If PerfMark is disabled, this method is a no-op. The name of the task should be a runtime-time constant, usually a string literal. Tasks with the same name can be grouped together for analysis later, so avoid using too many unique task names.

        This function has many more caveats than the traceTask(String) that accept a string. See the docs at attachTag(String, Object, StringFunction) for a list of risks associated with passing a function. Unlike other closeables, it is not safe to call close() more than once.

        Type Parameters:
        T - the object type to be stringified
        Parameters:
        taskNameObject - the name of the task.
        taskNameFunction - the function that will convert the taskNameObject to a taskName
        Returns:
        a closeable that must be closed at the end of the task
        Since:
        0.23.0
      • event

        public static void event​(java.lang.String eventName,
                                 Tag tag)
        Marks an event. Events are logically both a task start and a task end. Events have no duration associated. Events still represent the instant something occurs. If PerfMark is disabled, this method is a no-op.

        The tag is a run-time identifier for the event. It represents the dynamic part of the event, while the event name is the constant part of the event. While not always enforced, tags should not be null.

        Parameters:
        eventName - the name of the event.
        tag - a user provided tag for the event.
        Since:
        0.13.37
      • event

        public static void event​(java.lang.String eventName)
        Marks an event. Events are logically both a task start and a task end. Events have no duration associated. Events still represent the instant something occurs. If PerfMark is disabled, this method is a no-op.
        Parameters:
        eventName - the name of the event.
        Since:
        0.13.37
      • event

        public static void event​(java.lang.String eventName,
                                 java.lang.String subEventName)
        Marks an event. Events are logically both a task start and a task end. Events have no duration associated. Events still represent the instant something occurs. If PerfMark is disabled, this method is a no-op.
        Parameters:
        eventName - the name of the event.
        subEventName - the name of the sub event.
        Since:
        0.20.0
      • stopTask

        public static void stopTask()
        Marks the end of a task. If PerfMark is disabled, this method is a no-op.

        It is important that stopTask() always be called after starting a task, even in case of exceptions. Failing to do so may result in corrupted results.

        Since:
        0.22.0
      • stopTask

        public static void stopTask​(java.lang.String taskName,
                                    Tag tag)
        Marks the end of a task. If PerfMark is disabled, this method is a no-op. The task name and tag should match the ones provided to the corresponding startTask(String, Tag), if provided. If the task name or tag do not match, the implementation will prefer the starting name and tag. The name and tag help identify the task if PerfMark is enabled mid way through the task, or if the previous results have been overwritten. The name of the task should be a runtime-time constant, usually a string literal. Consider using stopTask() instead.

        It is important that stopTask() always be called after starting a task, even in case of exceptions. Failing to do so may result in corrupted results.

        Parameters:
        taskName - the name of the task being ended.
        tag - the tag of the task being ended.
        Since:
        0.13.37
      • stopTask

        public static void stopTask​(java.lang.String taskName)
        Marks the end of a task. If PerfMark is disabled, this method is a no-op. The task name should match the ones provided to the corresponding startTask(String), if provided. If the task name does not match, the implementation will prefer the starting name. The name helps identify the task if PerfMark is enabled mid way through the task, or if the previous results have been overwritten. The name of the task should be a runtime-time constant, usually a string literal. Consider using stopTask() instead.

        It is important that stopTask() always be called after starting a task, even in case of exceptions. Failing to do so may result in corrupted results.

        Parameters:
        taskName - the name of the task being ended.
        Since:
        0.13.37
      • stopTask

        public static void stopTask​(java.lang.String taskName,
                                    java.lang.String subTaskName)
        Marks the end of a task. If PerfMark is disabled, this method is a no-op. The task name should match the ones provided to the corresponding startTask(String, String), if provided. If the task name does not match, the implementation will prefer the starting name. The name helps identify the task if PerfMark is enabled mid way through the task, or if the previous results have been overwritten. The name of the task should be a runtime-time constant, usually a string literal. Consider using stopTask() instead.

        It is important that stopTask() always be called after starting a task, even in case of exceptions. Failing to do so may result in corrupted results.

        Parameters:
        taskName - the name of the task being ended.
        subTaskName - the name of the sub task being ended.
        Since:
        0.20.0
      • createTag

        public static Tag createTag()
        Creates a tag with no name or numeric identifier. The returned instance is different based on if PerfMark is enabled or not.

        This method is seldomly useful; users should generally prefer to use the overloads of methods that don't need a tag. An empty tag may be useful though when the tag of a group of tasks may change over time.

        Returns:
        a Tag that has no name or id.
        Since:
        0.13.37
      • createTag

        public static Tag createTag​(long id)
        Creates a tag with no name. The returned instance is different based on if PerfMark is enabled or not. The provided id does not have to be globally unique, but is instead meant to give context to a task.
        Parameters:
        id - a user provided identifier for this Tag.
        Returns:
        a Tag that has no name.
        Since:
        0.13.37
      • createTag

        public static Tag createTag​(java.lang.String name)
        Creates a tag with no numeric identifier. The returned instance is different based on if PerfMark is enabled or not. The provided name does not have to be globally unique, but is instead meant to give context to a task.
        Parameters:
        name - a user provided name for this Tag.
        Returns:
        a Tag that has no numeric identifier.
        Since:
        0.13.37
      • createTag

        public static Tag createTag​(java.lang.String name,
                                    long id)
        Creates a tag with both a name and a numeric identifier. The returned instance is different based on if PerfMark is enabled or not. Neither the provided name nor id has to be globally unique, but are instead meant to give context to a task.
        Parameters:
        id - a user provided identifier for this Tag.
        name - a user provided name for this Tag.
        Returns:
        a Tag that has both a name and id.
        Since:
        0.13.37
      • link

        @Deprecated
        public static Link link()
        Deprecated.
        DO NOT CALL, no longer implemented. Use linkOut() instead.
        Returns:
        a no-op link that
      • linkOut

        public static Link linkOut()
        A link connects between two tasks that start asynchronously. When linkOut() is called, an association between the most recently started task and a yet-to-be named task on another thread, is created. Links are a one-to-many relationship. A single started task can have multiple associated tasks on other threads.
        Returns:
        A Link to be used in other tasks.
        Since:
        0.17.0
      • linkIn

        public static void linkIn​(Link link)
        Associate this link with the most recently started task. There may be at most one inbound linkage per task: the first call to linkIn(io.perfmark.Link) decides which outbound task is the origin.
        Parameters:
        link - a link created inside of another task.
        Since:
        0.17.0
      • attachTag

        public static void attachTag​(Tag tag)
        Attaches an additional tag to the current active task. The tag provided is independent of the tag used with startTask(String, Tag) and stopTask(String, Tag). Unlike the two previous two task overloads, the tag provided to attachTag(Tag) does not have to match any other tags in use. This method is useful for when you have the tag information after the task is started.

        Here are some example usages:

        Recording the amount of work done in a task:

           byte[] data;
           try (var close = PerfMark.traceTask("read")) {
             data = file.read();
             PerfMark.attachTag(PerfMark.createTag("bytes read", data.length));
           }
         

        Recording a tag which may be absent on an exception:

           Socket s;
           Tag remoteTag = PerfMark.createTag(remoteAddress.toString());
           PerfMark.startTask("connect", remoteTag);
           try {
             s = connect(remoteAddress);
             PerfMark.attachTag(PerfMark.createTag(s.getLocalAddress().toString());
           } finally {
             PerfMark.stopTask("connect", remoteTag);
           }
         
        Parameters:
        tag - the Tag to attach.
        Since:
        0.18.0
      • attachTag

        public static void attachTag​(java.lang.String tagName,
                                     java.lang.String tagValue)
        Attaches an additional keyed tag to the current active task. The tag provided is independent of the tag used with startTask and stopTask. This tag operation is different than Tag in that the tag value has an associated name (also called a key). The tag name and value are attached to the most recently started task, and don't have to match any other tags. This method is useful for when you have the tag information after the task is started.
        Parameters:
        tagName - The name of the value being attached
        tagValue - The value to attach to the current task.
        Since:
        0.20.0
      • attachTag

        public static void attachTag​(java.lang.String tagName,
                                     long tagValue)
        Attaches an additional keyed tag to the current active task. The tag provided is independent of the tag used with startTask and stopTask. This tag operation is different than Tag in that the tag value has an associated name (also called a key). The tag name and value are attached to the most recently started task, and don't have to match any other tags. This method is useful for when you have the tag information after the task is started.
        Parameters:
        tagName - The name of the value being attached
        tagValue - The value to attach to the current task.
        Since:
        0.20.0
      • attachTag

        public static void attachTag​(java.lang.String tagName,
                                     long tagValue0,
                                     long tagValue1)
        Attaches an additional keyed tag to the current active task. The tag provided is independent of the tag used with startTask and stopTask. This tag operation is different than Tag in that the tag values have an associated name (also called a key). The tag name and values are attached to the most recently started task, and don't have to match any other tags. This method is useful for when you have the tag information after the task is started.

        This method may treat the given two longs as special. If the tag name contains the string "uuid" (case-insensitive), the value may be treated as a single 128 bit value. An example usage:

           RPC rpc = ...
           PerfMark.startTask("sendRPC");
           try {
             UUID u = rpc.uuid();
             PerfMark.attachTag("rpc uuid", u.getMostSignificantBits(), u.getLeastSignificantBits());
             send(rpc);
           } finally {
             PerfMark.stopTask("sendRPC");
           }
         
        Parameters:
        tagName - The name of the value being attached
        tagValue0 - The first value to attach to the current task.
        tagValue1 - The second value to attach to the current task.
        Since:
        0.20.0
      • attachStringTag

        public static <T> void attachStringTag​(java.lang.String tagName,
                                               T tagObject,
                                               java.util.function.Function<? super T,​? extends java.lang.String> stringFunction)
        Attaches an additional keyed tag to the current active task. The tag provided is independent of the tag used with startTask and stopTask. This tag operation is different than Tag in that the tag value has an associated name (also called a key). The tag name and value are attached to the most recently started task, and don't have to match any other tags. This method is useful for when you have the tag information after the task is started.

        Unlike attachTag(String, String), this defers constructing the tagValue String until later, and avoids doing any work while PerfMark is disabled. Callers are expected to provide a method handle that can consume the tagObject, and produce a tagValue. For example:

        
         Response resp = client.makeCall(request);
         PerfMark.attachTag("httpServerHeader", resp, r -> r.getHeaders().get("Server"));
         

        Also unlike attachTag(String, String), this function is easier to misuse. Prefer using the other attachTag methods unless you are confident you need this one. Be familiar with following issues:

        • Callers should be careful to not capture the tagObject, and instead use the argument to stringFunction. This avoids a memory allocation and possibly holding the tagObject alive longer than necessary.
        • The stringFunction should be idempotent, have no side effects, and be safe to invoke from other threads. If the string function references state that may be changed, callers must synchronize access. The string function may be called multiple times for the same tag object. Additionally, if attachTag() is called with the same tag object and string function multiple times, PerfMark may invoke the function only once.
        • The tag object may kept alive longer than normal, and prevent garbage collection from reclaiming it. If the tag object retains a large amount of resources, this may appear as a memory leak. The risk of this memory increase will need to be balanced with the cost of eagerly constructing the tag value string. Additionally, if the string function is a capturing lambda (refers to local or global state), the function itself may appear as a leak.
        • If the stringFunction is null, or if it throws an exception when called, the tag value will not be attached. It is implementation defined if such problems are reported (e.g. logged). Note that exceptions are expensive compared to PerfMark calls, and thus may slow down tracing. If an exception is thrown, or if the stringFunction is null, PerfMark may invoke other methods on the tag object or string function, such as toString() and getClass().
        Type Parameters:
        T - the type of tag object to be stringified
        Parameters:
        tagName - The name of the value being attached
        tagObject - The tag object which will passed to the stringFunction.
        stringFunction - The function that will convert the object to a tag
        Since:
        0.27.0
      • attachTag

        public static <T> void attachTag​(java.lang.String tagName,
                                         T tagObject,
                                         StringFunction<? super T> stringFunction)
        Attaches an additional keyed tag to the current active task. The tag provided is independent of the tag used with startTask and stopTask. This tag operation is different than Tag in that the tag value has an associated name (also called a key). The tag name and value are attached to the most recently started task, and don't have to match any other tags. This method is useful for when you have the tag information after the task is started.

        Prefer attachStringTag(String, Object, Function) over this one.

        Type Parameters:
        T - the type of tag object to be stringified
        Parameters:
        tagName - The name of the value being attached
        tagObject - The tag object which will passed to the stringFunction.
        stringFunction - The function that will convert the object to a tag
        Since:
        0.22.0
      • attachIntTag

        public static <T> void attachIntTag​(java.lang.String tagName,
                                            T tagObject,
                                            java.util.function.ToIntFunction<? super T> intFunction)
        Attaches an additional keyed tag to the current active task. The tag provided is independent of the tag used with startTask and stopTask. This tag operation is different than Tag in that the tag value has an associated name (also called a key). The tag name and value are attached to the most recently started task, and don't have to match any other tags. This method is useful for when you have the tag information after the task is started.
        Type Parameters:
        T - the type of tag object to mapped to in.
        Parameters:
        tagName - The name of the value being attached
        tagObject - The tag object which will passed to the intFunction.
        intFunction - The function that will convert the object to a tag
        Since:
        0.27.0
      • attachLongTag

        public static <T> void attachLongTag​(java.lang.String tagName,
                                             T tagObject,
                                             java.util.function.ToLongFunction<? super T> longFunction)
        Attaches an additional keyed tag to the current active task. The tag provided is independent of the tag used with startTask and stopTask. This tag operation is different than Tag in that the tag value has an associated name (also called a key). The tag name and value are attached to the most recently started task, and don't have to match any other tags. This method is useful for when you have the tag information after the task is started.
        Type Parameters:
        T - the type of tag object to mapped to in.
        Parameters:
        tagName - The name of the value being attached
        tagObject - The tag object which will passed to the intFunction.
        longFunction - The function that will convert the object to a tag
        Since:
        0.27.0