User login/Access logs

I would like to know what the best way to have user login logs is. I have read through the forum and seen a few posts that have some hints, but none of them has given me what I need. For now, my interest is to have a table in the database that has records of user logins and logouts. I have come across posts talking about an Audit logs module and the Usage Statistics module, but I have not found the solution to what I need since I have failed to get the module working. I keep getting an error about failure to create the usage statistics table in MySQL. I guess the fact that am pretty new to OpenMRS also has something to do with it :roll_eyes:

My overall objective is to build an analytics tool that reports on how many users have accessed/are aaccessing the system in various locations around the country (in real time), when and for how long. Maybe later, there might be a requirement on what the users did on the system.

Is the Usage Statistcs module my best option for this? If not, what is?

Thanks

@tsalira What version of openmrs are you running, also to what architecture and your use case. Data Entry Statistics see documentation and Usage Statistics see documentation will be a great start for you. Is refreshing to have someone thinking towards this direction. You as well mentioned

Do you have an online/real-time installation of openmrs? How do you intend to monitor these activities real-time?

Am running OpenMRS 2.0.6 Build 453af9 on Ubuntu 19.10 with MariaDB 10.4.8

Am developing on an offline installation (I should probably think about getting it online :thinking:). For now, am thinking of running a script (on the various host machines round the country) that queries the database for user login data every 5 minutes, and posts the data to a url for the Analytics tool. So my “real-time” is actually a 5 minutes interval giving users a glance of how many users in how many facilities are online and using the system.

It would be great if you can share the error log when you try to install these modules.

Ok, so when I try to install the Usage statistics module, I get the following errors:

WARN - Module.expandExtensionNames(546) |2019-11-25 06:20:34,564| usagestatistics: 
Unable to find class definition for extension: org.openmrs.patientDashboardTab
java.lang.NoClassDefFoundError: org/openmrs/module/web/extension/PatientDashboardTabExt
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:756)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:468)
at java.net.URLClassLoader.access$100(URLClassLoader.java:74)
at java.net.URLClassLoader$1.run(URLClassLoader.java:369)
at java.net.URLClassLoader$1.run(URLClassLoader.java:363)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:362)
at org.openmrs.module.ModuleClassLoader.loadClass(ModuleClassLoader.java:645)
at org.openmrs.module.ModuleClassLoader.loadClass(ModuleClassLoader.java:564)
at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
at org.openmrs.module.Module.expandExtensionNames(Module.java:538)
at org.openmrs.module.Module.getExtensions(Module.java:490)
at org.openmrs.module.ModuleFactory.startModuleInternal(ModuleFactory.java:664)
at org.openmrs.api.context.Daemon$1.run(Daemon.java:74)
Caused by: java.lang.ClassNotFoundException: org.openmrs.module.web.extension.PatientDashboardTabExt
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1856)
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1705)
at org.openmrs.module.ModuleClassLoader.loadClass(ModuleClassLoader.java:571)
at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
... 16 more

And

WARN - ModuleFactory.startModuleInternal(788) |2019-11-25 06:20:34,834| Error while trying to start module: usagestatistics
org.openmrs.api.db.DAOException: Error while running sql: CREATE TABLE `usagestatistics_encounter` (
		  `usage_id` int(11) NOT NULL,
		  `encounter_id` int(11) NOT NULL,
		  KEY `usagestatistics_encounter_usage` (`usage_id`),
		  KEY `usagestatistics_encounter_encounter` (`encounter_id`),
		  CONSTRAINT `usagestatistics_encounter_encounter` FOREIGN KEY (`encounter_id`) REFERENCES `encounter` (`encounter_id`),
		  CONSTRAINT `usagestatistics_encounter_usage` FOREIGN KEY (`usage_id`) REFERENCES `usagestatistics_usage` (`usage_id`) ON DELETE CASCADE
		) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED . Message: Can't create table `ugandaemr`.`usagestatistics_encounter` (errno: 140 "Wrong create options")
at org.openmrs.util.DatabaseUtil.populateResultsFromSQLQuery(DatabaseUtil.java:159)
at org.openmrs.util.DatabaseUtil.access$000(DatabaseUtil.java:34)
at org.openmrs.util.DatabaseUtil$1.execute(DatabaseUtil.java:98)
at org.hibernate.jdbc.WorkExecutor.executeWork(WorkExecutor.java:54)
at org.hibernate.internal.SessionImpl$2.accept(SessionImpl.java:2076)
at org.hibernate.internal.SessionImpl$2.accept(SessionImpl.java:2073)
at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.coordinateWork(JdbcCoordinatorImpl.java:313)
at org.hibernate.internal.SessionImpl.doWork(SessionImpl.java:2095)
at org.hibernate.internal.SessionImpl.doWork(SessionImpl.java:2080)
at org.openmrs.util.DatabaseUtil.executeSQL(DatabaseUtil.java:94)
at org.openmrs.api.db.hibernate.HibernateAdministrationDAO.executeSQL(HibernateAdministrationDAO.java:169)
at org.openmrs.api.impl.AdministrationServiceImpl.executeSQL(AdministrationServiceImpl.java:298)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
at com.sun.proxy.$Proxy67.executeSQL(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.openmrs.aop.LoggingAdvice.invoke(LoggingAdvice.java:121)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:52)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:52)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
at com.sun.proxy.$Proxy89.executeSQL(Unknown Source)
at org.openmrs.module.ModuleFactory.runDiff(ModuleFactory.java:940)
at org.openmrs.module.ModuleFactory.startModuleInternal(ModuleFactory.java:718)
at org.openmrs.api.context.Daemon$1.run(Daemon.java:74)
Caused by: java.sql.SQLException: Can't create table `ugandaemr`.`usagestatistics_encounter` (errno: 140 "Wrong create options")
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1086)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4237)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4169)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2617)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2778)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2825)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2156)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2441)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2366)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2350)
at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeUpdate(NewProxyPreparedStatement.java:147)
at org.openmrs.util.DatabaseUtil.populateResultsFromSQLQuery(DatabaseUtil.java:138)
... 42 more

And finally

log4j:ERROR A "org.apache.log4j.xml.DOMConfigurator" object is not assignable to a "org.apache.log4j.spi.Configurator" variable.
log4j:ERROR The class "org.apache.log4j.spi.Configurator" was loaded by 
log4j:ERROR [ClassRealm[plugin>org.openmrs.maven.plugins:openmrs-sdk-maven-plugin:3.13.2, parent: sun.misc.Launcher$AppClassLoader@1b6d3586]] whereas object of type 
log4j:ERROR "org.apache.log4j.xml.DOMConfigurator" was loaded by [{ModuleClassLoader: uid=932454877; ugandaemrsync}].
log4j:ERROR Could not instantiate configurator [org.apache.log4j.xml.DOMConfigurator].
log4j:ERROR Could not create an Appender. Reported error follows.
java.lang.ClassCastException: org.openmrs.util.MemoryAppender cannot be cast to org.apache.log4j.Appender
at org.apache.log4j.xml.DOMConfigurator.parseAppender(DOMConfigurator.java:238)
at org.apache.log4j.xml.DOMConfigurator.findAppenderByName(DOMConfigurator.java:171)
at org.apache.log4j.xml.DOMConfigurator.findAppenderByReference(DOMConfigurator.java:184)
at org.apache.log4j.xml.DOMConfigurator.parseChildrenOfLoggerElement(DOMConfigurator.java:502)
at org.apache.log4j.xml.DOMConfigurator.parseRoot(DOMConfigurator.java:471)
at org.apache.log4j.xml.DOMConfigurator.parse(DOMConfigurator.java:921)
at org.apache.log4j.xml.DOMConfigurator.doConfigure(DOMConfigurator.java:790)
at org.apache.log4j.xml.DOMConfigurator.doConfigure(DOMConfigurator.java:696)
at org.apache.log4j.helpers.OptionConverter.selectAndConfigure(OptionConverter.java:471)
at org.apache.log4j.LogManager.<clinit>(LogManager.java:125)
at org.apache.log4j.Logger.getLogger(Logger.java:105)
at org.apache.commons.logging.impl.Log4JLogger.getLogger(Log4JLogger.java:262)
at org.apache.commons.logging.impl.Log4JLogger.<init>(Log4JLogger.java:108)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.apache.commons.logging.impl.LogFactoryImpl.createLogFromClass(LogFactoryImpl.java:1025)
at org.apache.commons.logging.impl.LogFactoryImpl.discoverLogImplementation(LogFactoryImpl.java:844)
at org.apache.commons.logging.impl.LogFactoryImpl.newInstance(LogFactoryImpl.java:541)
at org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:292)
at org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:269)
at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:655)
at org.openmrs.module.ugandaemrsync.UgandaEMRSyncActivator.<init>(UgandaEMRSyncActivator.java:22)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at java.lang.Class.newInstance(Class.java:442)
at org.openmrs.module.Module.getModuleActivator(Module.java:156)
at org.openmrs.module.ModuleFactory.startModuleInternal(ModuleFactory.java:770)
at org.openmrs.api.context.Daemon$1.run(Daemon.java:74)
log4j:ERROR Could not parse url [file:/home/tonny/openmrs/ugandaemr/tmp/openmrs/WEB-INF/classes/log4j.xml].
java.lang.NullPointerException
at java.util.Hashtable.put(Hashtable.java:460)
at org.apache.log4j.xml.DOMConfigurator.findAppenderByName(DOMConfigurator.java:172)
at org.apache.log4j.xml.DOMConfigurator.findAppenderByReference(DOMConfigurator.java:184)
at org.apache.log4j.xml.DOMConfigurator.parseChildrenOfLoggerElement(DOMConfigurator.java:502)
at org.apache.log4j.xml.DOMConfigurator.parseRoot(DOMConfigurator.java:471)
at org.apache.log4j.xml.DOMConfigurator.parse(DOMConfigurator.java:921)
at org.apache.log4j.xml.DOMConfigurator.doConfigure(DOMConfigurator.java:790)
at org.apache.log4j.xml.DOMConfigurator.doConfigure(DOMConfigurator.java:696)
at org.apache.log4j.helpers.OptionConverter.selectAndConfigure(OptionConverter.java:471)
at org.apache.log4j.LogManager.<clinit>(LogManager.java:125)
at org.apache.log4j.Logger.getLogger(Logger.java:105)
at org.apache.commons.logging.impl.Log4JLogger.getLogger(Log4JLogger.java:262)
at org.apache.commons.logging.impl.Log4JLogger.<init>(Log4JLogger.java:108)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.apache.commons.logging.impl.LogFactoryImpl.createLogFromClass(LogFactoryImpl.java:1025)
at org.apache.commons.logging.impl.LogFactoryImpl.discoverLogImplementation(LogFactoryImpl.java:844)
at org.apache.commons.logging.impl.LogFactoryImpl.newInstance(LogFactoryImpl.java:541)
at org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:292)
at org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:269)
at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:655)
at org.openmrs.module.ugandaemrsync.UgandaEMRSyncActivator.<init>(UgandaEMRSyncActivator.java:22)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at java.lang.Class.newInstance(Class.java:442)
at org.openmrs.module.Module.getModuleActivator(Module.java:156)
at org.openmrs.module.ModuleFactory.startModuleInternal(ModuleFactory.java:770)
at org.openmrs.api.context.Daemon$1.run(Daemon.java:74)

When I remove the the usagestatistics-1.4.2.omod file from the modules folder, OpenMRS runs well.

The error logs can be found at https://pastebin.com/rEVAbLjB

To make this thread smaller, can you use something like pastebin.com for the logs? Then you can edit your previous post and replace the log with paste links.

1 Like