I asked this on someone else's question: https://community.atlassian.com/t5/Confluence-questions/How-to-query-active-users-in-Confluence/qaq-p/24532?_ga=2.208006866.1942474880.1528220541-1332829241.1528220541 but never got a response, so I'm re-asking it as it's own question now.
When we were under 500 users the below macro worked perfectly for me; however, now that we are over 900 users - the system times out. Is there a better way to get all Confluence users name and last login for audit purposes?
## Macro title: Last Login ## Macro has a body: N ## Body processing: Selected body processing option ## Output: Selected output option ## ## Developed by: Andrew Frayling ## Date created: 11/02/2012 ## Installed by: <your name> ## Macro to display the last login date of users who have access to the current space ## @noparams #set($containerManagerClass = $content.class.forName('com.atlassian.spring.container.ContainerManager')) #set($getInstanceMethod = $containerManagerClass.getDeclaredMethod('getInstance',null)) #set($containerManager = $getInstanceMethod.invoke(null,null)) #set($containerContext = $containerManager.containerContext) #set($loginManager = $containerContext.getComponent('loginManager')) #set($users = $userAccessor.getUsers()) <table class="confluenceTable"> <tr> <th class="confluenceTh">User</th> <th class="confluenceTh">Last Successful Login</th> </tr> #foreach($user in $users) ## list the last login date of users who can view the current space <tr> <td class="confluenceTd">#usernameLink($user.name)</td> #if (!$loginManager.getLoginInfo($user).lastSuccessfulLoginDate) <td class="confluenceTd" style="background-color:#ff0000"><strong>NEVER</strong></td> #else <td class="confluenceTd">$action.dateFormatter.formatDateTime($loginManager.getLoginInfo($user).lastSuccessfulLoginDate)</td> #end </tr> #end </table>
Hi @mary.moore,
it looks like you've reached the limit of what can be reasonably achieved with User Macros. You might be able to find some short-term workarounds but sooner or later you'll hit the same or similar problems as this solution obviously doesn't scale.
A better approach would be to directly query the Confluence database for this kind of data. There's an official Atlassian article that presents some example Queries for this. Using SQL queries you are so much more flexible and it's much more performant.
To get the exact same data that your User Macro currently generates you could use this SQL:
SELECT cu.user_name,
li.successdate
FROM cwd_user cu
JOIN user_mapping um ON um.username = cu.user_name
LEFT JOIN logininfo li ON li.username = um.user_key
ORDER BY li.successdate;
If you want to display your data in Confluence you could simply use PocketQuery to do so. With a few modifications to the standard PocketQuery template you can even get the same representation as from your User Macro:
This is the PocketQuery Template code I've used:
<table class="aui confluenceTable pocketquery-table">
<thead>
<tr>
<th class="confluenceTh">User</th>
<th class="confluenceTh">Last Successful Login</th>
</tr>
</thead>
<tbody>
#foreach ($user in $result)
<tr>
<td class="confluenceTd">#usernameLink($user.user_name)</td>
#if($user.successdate)
<td class="confluenceTd">$dateFormatter.formatDateTime($user.successdate)</td>
#else
<td class="confluenceTd" style="background-color:#ff0000"><strong>NEVER</strong></td>
#end
</tr>
#end
</tbody>
</table>
So what's the difference between row 2 (PocketQuery) and 3 (User Macro) in the image now?
I hope this helps! :)
Best regards,
Sven
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.