0

I am new to neo4j and I want to develop a plugin that registers changes in database to a log, for now i only want log transaction data. I am using maven with java 17 to build the jar and Docker to deploy neo4j with the latest image (5.10.0).

The plugin looks like this:

Class to handle logging events:

public class Neo4jTriggersPlugin implements TransactionEventListener<Object> {
    private final Log log;


    public Neo4jTriggersPlugin(DatabaseManagementService dbms, LogService lgsvc) {
        this.log = lgsvc.getUserLog(Neo4jTriggersPlugin.class);
    }

    @Override
    public Object beforeCommit(TransactionData transactionData, Transaction transaction, GraphDatabaseService graphDatabaseService) throws Exception {
        return null;
    }

    @Override
    public void afterCommit(TransactionData transactionData, Object o, GraphDatabaseService graphDatabaseService) {
        log.info("Transaction committed" + transactionData.toString());
    }

    @Override
    public void afterRollback(TransactionData transactionData, Object o, GraphDatabaseService graphDatabaseService) {
    }

public class LifecycleManagement extends ExtensionFactory<LifecycleManagement.Dependencies> {
    private Log logger;
    @Override
    public Lifecycle newInstance(ExtensionContext extensionContext, final Dependencies dependencies) {
        return new LifecycleAdapter() {
            LogService logService = dependencies.log();
            private Neo4jTriggersPlugin triggersPlugin;

            @Override
            public void start() {
                System.out.println("STARTING trigger watcher");
                triggersPlugin = new Neo4jTriggersPlugin(dependencies.getGraphDatabaseService(), logService);
                dependencies.getGraphDatabaseService().registerTransactionEventListener("neo4j", triggersPlugin);
            }

            @Override
            public void shutdown() {
                System.out.println("STOPPING trigger watcher");
                dependencies.getGraphDatabaseService().unregisterTransactionEventListener("neo4j",triggersPlugin);
            }
        };
    }

    interface Dependencies {
        DatabaseManagementService getGraphDatabaseService();
        LogService log();
    }

    public LifecycleManagement(Log log) {
        super(ExtensionType.DATABASE, "registerTransactionEventHandler");
        this.logger = null;
    }

I found example here. I went through neo4j documentation about logging, procedures, extensions etc.

After I compile and build the .jar of the above plugin, I copy it into var/lib/neo4j/plugins/ directory and restart the container. Then I run some cypher queries and I do not see any info written in a log. Also I have mounted the /logs and /data/database as volumes.

I would appreciate if someone could explain how this is done corretly or point me to a good source of information. Thanks.

cybersam
  • 63,203
  • 6
  • 53
  • 76
matej
  • 1
  • 1
  • Does the example plugin (which is pretty old) work as-is? If so, see what you are doing differently. – cybersam Jul 28 '23 at 17:37
  • @cybersam I have tried using @Context annotation with the `org.neo4j.logging.Log` which should inject the logger provided by the database, did not work, perhaps ther is something with compiling/building .jar? I am using build dependencies provided here from official Neo4j template – matej Jul 28 '23 at 19:57
  • The [Context](https://neo4j.com/docs/java-reference/current/extending-neo4j/procedures/#injectable-resources) annotation is only documented to work with [user-defined procedures](https://neo4j.com/docs/java-reference/current/extending-neo4j/procedures/) that are explicitly invoked via Cypher. Your plugin does not define a procedure. – cybersam Jul 28 '23 at 20:09
  • I have annotated LifecycleManagment class with `@ServiceProvider` and now I am getting prints on the docker log with stdout and it is initializing the plugin, I am also getting comitted transaction in the callback. I am still trying to figure out how to correctly wire through logger @cybersam – matej Jul 28 '23 at 21:11
  • Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. – Lore Jul 29 '23 at 13:30
  • @matej See my answer for a workaround to implementing the logging yourself. – cybersam Jul 31 '23 at 16:08

2 Answers2

0

You need to get the logger from the Dependencies , you can check an example here

https://github.com/ikwattro/neo4j-transaction-event-listener-extension/blob/master/src/main/java/com/ikwattro/neo4j/tx/MyExtensionFactory.java#L31

Christophe Willemsen
  • 19,399
  • 2
  • 29
  • 36
-1

As a workaround, your plugin can invoke the extended APOC apoc.log procedures (e.g., apoc.log.info) to log to neo4j.log on the server.

Also, instead of writing your own commit-triggered plugin, you may want to use APOC's trigger procedures instead.

cybersam
  • 63,203
  • 6
  • 53
  • 76