Version 7

    This JSP code presents the logged history of a process instance, with log entries grouped by token.  Displayed are date/time, an activity composed of relavent data based on the log type, the responsible actor (currently not logged), and the name of the associated token (blank for the root token).  And...remember that if you don't call jbpmContext.save(myProcessInstance) after advancing the process, your logs won't be persisted!

    <%@ page import="java.util.*,
                     java.text.*"
    %>
    <%@ page import="org.hibernate.*"
    %>
    <%@ page import="org.jbpm.graph.def.*,
                    org.jbpm.graph.exe.*,
                    org.jbpm.graph.node.*,
                    org.jbpm.jpdl.xml.*,
                    org.jbpm.*,
                    org.jbpm.db.*,
                    org.jbpm.context.exe.*,
                    org.jbpm.logging.log.*,
                    org.jbpm.graph.log.*,
                    org.jbpm.taskmgmt.log.*,
                    org.jbpm.context.log.*"
    %>
    
    <% 
    long id =  Long.parseLong(request.getParameter("instanceId"));
    JbpmContext jbpmContext = null;
    try{
    
    jbpmContext = JbpmConfiguration.getInstance().createJbpmContext();
    GraphSession graphSession = jbpmContext.getGraphSession();
    TaskMgmtSession taskMgmtSession = jbpmContext.getTaskMgmtSession();
    
    ProcessInstance pi = graphSession.loadProcessInstance(id);
    ProcessDefinition pd = pi.getProcessDefinition();
    
    if("rollbackTo".equals(request.getParameter("action"))) {
        String logEntryId = request.getParameter("logEntryId");
        String processId = request.getParameter("processId");
        java.util.Date date = null;
        
        //this isn't working right now, so...
        System.out.println("this isn't working right now");
    }
    
    SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    %>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    <html>
    <body>
    <div id="mBody">
          <table width="90%" align="center" border="1" cellpadding="3" cellspacing="1" >
            <tr>
              <th colspan=6> <big>Log, Process Instance: <%=pi.getId()%></big> <small>(<%=pd.getName()%>
                   ver. <%=pd.getVersion()%>)</small><br>
            </tr>
            <tr>
              <th> DATE</th>
              <th> ACTIVITY</th>
              <th> ACTOR</th>
              <th> TOKEN</th>
              <th> Rollback</th>
            </tr>
      <%
      //SortedSet sortedEntries = new TreeSet();
      String logTxt = "";
      // returns all process instance logs, grouped by token...
      Map logsByToken = jbpmContext.getLoggingSession().findLogsByProcessInstance(pi.getId());
      Set keys = logsByToken.keySet();
      Iterator itr = keys.iterator();
      while(itr.hasNext()) {
          Token t = (Token)itr.next();
          List logs = (List)logsByToken.get(t);
          //sortedEntries.addAll(logs);
          Iterator itr2 = logs.iterator();
          while(itr2.hasNext()) {
              ProcessLog pl = (ProcessLog)itr2.next();
              if(pl instanceof ProcessInstanceCreateLog) {
                  logTxt = pl.toString();
              }else if(pl instanceof ProcessInstanceEndLog) {
                  logTxt = pl.toString();
              }else if(pl instanceof CompositeLog) {
                  if(pl instanceof SignalLog) {
                      logTxt = pl.toString();
                  }else if(pl instanceof TransitionLog) {
                    logTxt = pl.toString();
                  }else  if(pl instanceof ActionLog) {
                    logTxt = pl.toString();
                  }
              }else if(pl instanceof NodeLog) {
                  NodeLog nl = (NodeLog)pl;
                  logTxt = "node(exit)["+nl.getNode().getName()+", duration: "+nl.getDuration()+"ms]";
              }else if(pl instanceof TokenCreateLog) {
                  logTxt = pl.toString();
              }else if(pl instanceof TokenEndLog) {
                  logTxt = pl.toString();
              }else if(pl instanceof MessageLog) {
                  MessageLog ml = (MessageLog)pl;
                  logTxt = "message["+ml.getMessage()+"]";
              }else if(pl instanceof SwimlaneLog) {
                  if(pl instanceof SwimlaneCreateLog) {
                      logTxt = pl.toString();
                  }else if(pl instanceof SwimlaneAssignLog) {
                      SwimlaneAssignLog sal = (SwimlaneAssignLog)pl;
                      logTxt = "swimlane-assign["+sal.getSwimlaneOldActorId()+"-->"+sal.getSwimlaneNewActorId()+"]";
                  }
              }else if(pl instanceof TaskLog) {
                  if(pl instanceof TaskCreateLog) {
                      TaskCreateLog tcl = (TaskCreateLog)pl;
                      logTxt = "task-create["+tcl.getTaskInstance().getName()+" id: "+tcl.getTaskInstance().getId()+"]" +
                              " by "+tcl.getActorId();
                  }else if(pl instanceof TaskAssignLog) {
                      TaskAssignLog tal = (TaskAssignLog)pl;
                      logTxt = "task-assign["+tal.getTaskInstance().getName()+" id: "+tal.getTaskInstance().getId()+", " +
                              tal.getTaskOldActorId()+"-->"+tal.getTaskNewActorId()+"]" + " by "+tal.getActorId();
                  }else if(pl instanceof TaskEndLog) {
                      TaskEndLog tel = (TaskEndLog)pl;
                      logTxt = "task-end["+tel.getTaskInstance().getName()+" id: "+tel.getTaskInstance().getId()+"]" +
                              " by "+tel.getActorId();
                  }
              }else if(pl instanceof VariableLog) {
                  if(pl instanceof VariableCreateLog) {
                      logTxt = pl.toString();
                  }else if(pl instanceof VariableUpdateLog) {
                      logTxt = pl.toString();
                  }else if(pl instanceof VariableDeleteLog) {
                      logTxt = pl.toString();
                  }
              }%>
            <tr>
            <td><%=dateFormatter.format(pl.getDate())%></td>
            <td><%=logTxt%> <small>(pl: <%=pl.getId()%>)</small></td>
            <td><%= pl.getActorId() == null ? "" : pl.getActorId() %></td>
            <td><%= t.getName() == null ? "" : t.getName() %></td>
            <td><a href="log.jsp?action=rollbackTo&instanceId=<%= pi.getId() %>&logEntryId=<%= pl.getId() %>
                      " title="roll back to this date (if possible)">rollback</a></td>
            </tr>
              <%
          }
      }
      %>
       <tr>
          <td colspan=5>
          <a href="../index.jsp">home</a>   
          <a href="deployList.jsp">deployed flows</a>  
          <a href="instances.jsp?procDefName=<%=pd.getName()%>">instances</a>  
          <a href="nodes.jsp?procDefName=<%=pd.getName()%>&ver=<%=pd.getVersion()%>">definition nodes</a> 
          <a href="instance.jsp?id=<%=pi.getId()%>">instance</a>  
        </tr>
    </table>
    </div> 
    <%  
       }finally{
        jbpmContext.close();
       }
    %>
    </body>
    </html>
    

    Enjoy!