Is it possible to parse the user activity of a Lotus Notes database? I want to remove automatic access to the Lotus Notes database (by agents or servers), using LotusScript.
VIEW MEMBER FEEDBACK TO THIS ASK THE EXPERT Q&A.
Absolutely. First you will need to visit http://www-10.lotus.com/ldd/sandbox.nsf and search for "UserActivity". Download the "NotesUserActivity Class" file. This is a sample Lotus Notes database containing a script library called "CLASSUserActivity."
When you look at this library, you will see only one subroutine. That's because in Lotus Notes, classes are defined in the "Declarations" section, so this library is basically one giant declaration (thus explaining why no one uses OOP or classes in LotusScript!).
I'm going to give you the LotusScript code you need to use this beastie, thus you'll have to find something else to spend the next two weeks figuring out.
I'll warn you -- pulling the usage history from each Lotus Notes database is fairly time consuming. In this code, lifted directly from my production application inventory crawler, Names2exclude lists the Lotus Domino servers, developers and administrators to ignore.
The usage counters here are declared globally, because the routine must be called once on each Lotus Domino server where a replica of the Lotus Notes database resides. Since each replica copy of a database has its own independent history, in this way the usage from all Lotus Domino server replica copies can be aggregate.
Const Names2exclude= "CORPAGENTSIGNER~APPS001~CREGG S HARDWICK" Dim WeekUses As Long, WeekReads As Long,WeekWrites As Long Dim MonthUses As Long,MonthReads As Long,MonthWrites As Long Dim totaluses As Long,totalreads As Long,totalwrites As Long Sub GetUserActivity(db As NotesDatabase) Dim ua As New NotesUserActivity(db) Dim uae As notesuseractivityentry If ua.HasUserActivity Then weekUses=ua.PrevWeekUses weekReads=ua.PrevWeekReads weekWrites=ua.PrevWeekWrites monthUses=ua.PrevmonthUses monthReads=ua.PrevmonthReads monthWrites=ua.PrevmonthWrites totalUses=ua.Uses totalReads=ua.Reads totalWrites=ua.Writes Dim ActivityEntries As Long ActivityEntries=ua.UserActivityCount If ActivityEntries>0 Then Print " -- Reading "+ Format(ActivityEntries,"###,##0")+_ " history records..." End If Dim index As Variant,result As Variant Dim AIndex As Long For AIndex = 1 To ActivityEntries Set uae = ua.GetNthUserActivityEntry(AIndex) result=Evaluate ({@Name([Abbreviate];"}+_ uae.UserName+{"):@Name([cn];"}+_ uae.UserName+{")}) If Instr(names2exclude,Ucase(result(1)))=0 Then index=Arraygetindex(UserList,result(0)) If Isnull(index) Then If users<=maxusers Then Redim Preserve UserList(Users) As String Redim Preserve readsList(Users) As Long Redim Preserve writesList(Users) As Long Redim Preserve sessionList(Users) As Long Redim Preserve timeList(Users) As String UserList(Users)=result(0) timelist(users)=uae.time sessionList(Users)=1 readsList(Users)=uae.reads writeslist(users)=uae.writes Users=Users+1 End If Else sessionList(Index)=sessionList(Index)+1 readsList(Index)=readsList(Index)+uae.reads writeslist(Index)=writeslist(Index)+uae.writes End If End If Next AIndex End If End Sub
MEMBER FEEDBACK TO THIS ASK THE EXPERT Q&A:
I still have a problem with this code. When I try to save the agent I get the following error: "Reference occurs before declaration:UserList"
Allow me to point out that the variable is only declared three lines later.
If Instr(names2exclude,Ucase(result(1)))=0 Then index=Arraygetindex(UserList,result(0)) If Isnull(index) Then If users<=maxusers Then Redim Preserve UserList(Users) As String Redim Preserve readsList(Users) As Long Redim Preserve writesList(Users) As Long Redim Preserve sessionList(Users) As Long Redim Preserve timeList(Users) As String UserList(Users)=result(0) timelist(users)=uae.time sessionList(Users)=1 readsList(Users)=uae.reads writeslist(users)=uae.writes Users=Users+1 End If Else sessionList(Index)=sessionList(Index)+1 readsList(Index)=readsList(Index)+uae.reads writeslist(Index)=writeslist(Index)+uae.writes End If End If Next AIndex
—Wannes R.
******************************************
My apologies, I left out part of the Global Declarations section needed to support the GetUserActivity subroutine. Of course if -- in my production application, I had taken the time to compartmentalize this code in its own script library, then such a mistake would have been much harder to make!
To fix it, add the following to the Declarations section of your agent:
Dim users As Long Dim UserList() As String Dim readsList() As Long Dim writesList() As Long Dim timelist() As String Dim sessionList() As Long
Once more, the agent or script library should be set up as follows:
In the Options section:
'Option Public Use "CLASSUserActivity" Const Names2exclude= "CORPAGENTSIGNER~APPS001 ~CREGG S HARDWICK"The Declarations section:
Dim totaluses As Long,totalreads Dim WeekUses As Long, WeekReads As Long,WeekWrites As Long Dim MonthUses As Long, MonthReads As Long, MonthWrites As Long , totalwrites As Long Dim users As Long Dim UserList() As String Dim readsList() As Long Dim writesList() As Long Dim timelist() As String Dim sessionList() As Long The initialize event for a test agent that will call it: Sub Initialize Dim db As New notesdatabase("","") Call db.OpenByReplicaID (YOURSERVER,YOURDBREPLICAID) Call GetUserActivity(db) ' Access the global variables above to get results… End SubThe subroutine that does the work:
Sub GetUserActivity(db As NotesDatabase) Dim ua As New NotesUserActivity(db) Dim uae As notesuseractivityentry If ua.HasUserActivity Then weekUses=ua.PrevWeekUses weekReads=ua.PrevWeekReads weekWrites=ua.PrevWeekWrites monthUses=ua.PrevmonthUses monthReads=ua.PrevmonthReads monthWrites=ua.PrevmonthWrites totalUses=ua.Uses totalReads=ua.Reads totalWrites=ua.Writes Dim ActivityEntries As Long ActivityEntries=ua.UserActivityCount If ActivityEntries>0 Then Print " -- Reading "+Format(ActivityEntries,"###,##0") +" history records..." End If Dim index As Variant,result As Variant Dim AIndex As Long For AIndex = 1 To ActivityEntries Set uae = ua.GetNthUserActivityEntry(AIndex) result=Evaluate({@Name([Abbreviate];"} +uae.UserName+{"):@Name([cn];"} +uae.UserName+{")}) If Instr(names2exclude,Ucase(result(1)))=0 Then index=Arraygetindex(UserList,result(0)) If Isnull(index) Then If users<=maxusers Then Redim Preserve UserList(Users) As String Redim Preserve readsList(Users) As Long Redim Preserve writesList(Users) As Long Redim Preserve sessionList(Users) As Long Redim Preserve timeList(Users) As String UserList(Users)=result(0) timelist(users)=uae.time sessionList(Users)=1 readsList(Users)=uae.reads writeslist(users)=uae.writes Users=Users+1 End If Else sessionList(Index)=sessionList(Index)+1 readsList(Index)=readsList(Index)+uae.reads writeslist(Index)=writeslist(Index)+uae.writes End If End If Next AIndex End If End Sub
—Cregg Hardwick, LotusScript expert
Do you have comments on this Ask the Expert Q&A? Let us know.