<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: seyed mojtaba shadab</title>
    <description>The latest articles on DEV Community by seyed mojtaba shadab (@shaadcode).</description>
    <link>https://dev.to/shaadcode</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2895375%2Fb01f1045-84c0-40ab-937f-4156a274202f.jpg</url>
      <title>DEV Community: seyed mojtaba shadab</title>
      <link>https://dev.to/shaadcode</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/shaadcode"/>
    <language>en</language>
    <item>
      <title>Exploring customLogger: Smart, Customizable Logging in Payload CMS</title>
      <dc:creator>seyed mojtaba shadab</dc:creator>
      <pubDate>Tue, 27 May 2025 05:51:03 +0000</pubDate>
      <link>https://dev.to/shaadcode/exploring-customlogger-smart-customizable-logging-in-payload-cms-10kc</link>
      <guid>https://dev.to/shaadcode/exploring-customlogger-smart-customizable-logging-in-payload-cms-10kc</guid>
      <description>&lt;h2&gt;
  
  
  🧾 Brief Introduction to Payload CMS
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://payloadcms.com/" rel="noopener noreferrer"&gt;Payload CMS&lt;/a&gt;&lt;/strong&gt; is a &lt;strong&gt;Headless&lt;/strong&gt; content management system based on Node.js and TypeScript, designed for developers. Unlike many traditional CMSs that come with pre-built UIs or themes, Payload focuses on providing a developer-centric, API-driven, and customizable experience.&lt;/p&gt;

&lt;h3&gt;
  
  
  🎯 Key Features of Payload:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;TypeScript-first&lt;/strong&gt; structure: All structures, data models, and configurations are defined with the powerful TypeScript type system.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modern admin interface&lt;/strong&gt;: Automatically generates a complete content management UI from your schema.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Built-in security and authentication&lt;/strong&gt;: It has a built-in, extensible authentication and access control system.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hooks and Plugins Support&lt;/strong&gt;: You can control the behavior of the system precisely using hooks and plugins.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Payload allows developers to create a highly customizable, secure, and extensible content management system without being limited to predefined structures. That is why it is a popular choice for complex, custom, and modern projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔍 What is the &lt;code&gt;payload-auditor&lt;/code&gt; plugin?
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;&lt;code&gt;payload-auditor&lt;/code&gt;&lt;/strong&gt; plugin is a powerful plugin for Payload CMS that allows for precise &lt;strong&gt;audit&lt;/strong&gt; of operations performed on collections. The plugin automatically records all changes such as &lt;strong&gt;create&lt;/strong&gt;, &lt;strong&gt;update&lt;/strong&gt;, and &lt;strong&gt;delete&lt;/strong&gt; data and stores them in a structured log format.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✨ The main goal of this plugin:
&lt;/h3&gt;

&lt;p&gt;Provide a transparent and reliable logging system for monitoring user behavior and reviewing database-level change history.&lt;/p&gt;

&lt;h3&gt;
  
  
  ⚙️ Key features:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Automatic logging of operations on collections&lt;/li&gt;
&lt;li&gt;Support for defining &lt;strong&gt;custom logger&lt;/strong&gt; for custom logging&lt;/li&gt;
&lt;li&gt;Support for all CMS payload hooks&lt;/li&gt;
&lt;li&gt;Modular design with extensibility for complex projects&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using this plugin, developers and system administrators can easily understand who, when, and what changes were made to the system; a vital feature for projects where security, transparency, and audit trails are of high importance. To learn more about this plugin, you can read the article &lt;a href="https://dev.to/shaadcode/tracking-and-security-in-payload-cms-with-the-payload-auditor-plugin-mpk"&gt;Tracking and Security in Payload CMS with the Payload-Auditor Plugin&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  📚 The importance of custom logging in content management systems (CMS)
&lt;/h2&gt;

&lt;p&gt;In content management systems, especially in enterprise or sensitive projects, &lt;strong&gt;accurate tracking of user activities and data changes&lt;/strong&gt; plays a very important role. While basic logging can capture general information about operations, custom logging allows for &lt;strong&gt;accurate, targeted, and analyzable information&lt;/strong&gt; to be stored for the specific needs of each project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why do we need custom logging?
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. 🎯 Customization
&lt;/h4&gt;

&lt;p&gt;Projects are different; one project may need to record user IP, another may want to store user roles or geographic information. Custom logging allows for &lt;strong&gt;critical information tailored to the project scenario&lt;/strong&gt; to be recorded.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. 🕵️‍♀️ Transparency and Audit Trail
&lt;/h4&gt;

&lt;p&gt;For systems that require user behavior to be investigated or security issues to be addressed, the &lt;strong&gt;complete change trail&lt;/strong&gt; (who changed what, when, and how) must be clearly visible. This transparency cannot be achieved without accurate and customized logging.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. 🔐 Security and Accountability
&lt;/h4&gt;

&lt;p&gt;In many projects, especially in areas such as finance, medicine or government, accurate recording of activities plays an important role in &lt;strong&gt;data security and user accountability&lt;/strong&gt;. Custom logs can also be used as legal evidence.&lt;/p&gt;

&lt;h4&gt;
  
  
  4. 📊 Analytics and Intelligence
&lt;/h4&gt;

&lt;p&gt;With rich and structured logs, you can analyze user behavior, identify process weaknesses and ultimately make &lt;strong&gt;more informed decisions&lt;/strong&gt; to improve system performance.&lt;/p&gt;

&lt;p&gt;Logging is not just a monitoring tool; it is an integral part of &lt;strong&gt;security, optimization and professional management of content systems&lt;/strong&gt;. By providing the ability to record custom logs, you can have much more control and insight into what is happening in the system.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔧 What is &lt;code&gt;customLogger&lt;/code&gt;?
&lt;/h2&gt;

&lt;p&gt;In the &lt;code&gt;payload-auditor&lt;/code&gt; plugin, the &lt;code&gt;customLogger&lt;/code&gt; feature allows developers to &lt;strong&gt;fully customize logging behavior at the hook level&lt;/strong&gt;. This feature is designed for projects that need to generate or modify log content in a specific way depending on different conditions, since it is almost impossible to predict the default values for logging in the logs.&lt;/p&gt;

&lt;h3&gt;
  
  
  🧩 Defining &lt;code&gt;customLogger&lt;/code&gt; at the Hook Level
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;customLogger&lt;/code&gt; is an &lt;strong&gt;optional&lt;/strong&gt; function that can be specified in the &lt;code&gt;payload-auditor&lt;/code&gt; plugin configuration. This function is called when the hook used for each operation is executed and can &lt;strong&gt;edit or overwrite&lt;/strong&gt; the log data before final storage.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;customLogger&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Parameters&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;AllCollectionHooks&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;afterChange&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Omit&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;AuditorLog&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hook&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Omit&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;AuditorLog&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hook&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;Omit&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;AuditorLog&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hook&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this function:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;args&lt;/code&gt;: Contains information about the hook for the same document and can have values like &lt;code&gt;req&lt;/code&gt;, &lt;code&gt;operation&lt;/code&gt;, &lt;code&gt;doc&lt;/code&gt;, etc.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;fields&lt;/code&gt;: Contains the default log structure without the &lt;code&gt;hook&lt;/code&gt; field (because the principle of which hook created this log should not change).&lt;/li&gt;
&lt;li&gt;The output of the function should be a final version of &lt;code&gt;AuditorLog&lt;/code&gt; (except for the &lt;code&gt;hook&lt;/code&gt; added by the plugin).&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  🔀 Multi-level &lt;code&gt;customLoggers&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;In &lt;code&gt;payload-auditor&lt;/code&gt;, we have considered four levels of the customLogger function to increase flexibility.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔢 &lt;code&gt;customLogger&lt;/code&gt; definition levels (in order of execution priority):
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. 🥇 Operation-Level
&lt;/h4&gt;

&lt;p&gt;At this level, a dedicated &lt;code&gt;customLogger&lt;/code&gt; can be defined for each specific operation (&lt;code&gt;create&lt;/code&gt;, &lt;code&gt;update&lt;/code&gt;, &lt;code&gt;delete&lt;/code&gt;). This level has the &lt;strong&gt;highest execution priority&lt;/strong&gt; and if it exists, no other levels will be executed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;customLogger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nx"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;📌 Applies only to that specific operation&lt;br&gt;
✅ Has the highest priority&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h4&gt;
  
  
  2. 🥈 Hook-Level
&lt;/h4&gt;

&lt;p&gt;If &lt;code&gt;customLogger&lt;/code&gt; is not defined for a specific operation, the system looks for &lt;code&gt;customLogger&lt;/code&gt; at the hook level, such as &lt;code&gt;afterChange&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;customLogger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;📌 Only for &lt;strong&gt;specific hook&lt;/strong&gt; (e.g. afterChange)&lt;br&gt;
❌ Not executed if &lt;code&gt;customLogger&lt;/code&gt; is defined as an operation level&lt;br&gt;
✅ Only works on active operations&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h4&gt;
  
  
  3. 🥉 All Hooks Level (Hooks-Level)
&lt;/h4&gt;

&lt;p&gt;At this level, &lt;code&gt;customLogger&lt;/code&gt; is applied to &lt;strong&gt;all hooks and operations&lt;/strong&gt;, if none of the previous two levels exist.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;customLogger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;📌 Only runs if there is no logger at the hook and operation level&lt;br&gt;
✅ Only works on active operations&lt;br&gt;
❌ Cannot be defined for a specific hook – covers the entire hook system&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h4&gt;
  
  
  4. 🏁 Global-Level
&lt;/h4&gt;

&lt;p&gt;If no &lt;code&gt;customLogger&lt;/code&gt; is defined at the operation, hook or all hooks level, then the global &lt;code&gt;customLogger&lt;/code&gt; is run. This level works for &lt;strong&gt;all collections&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;customLogger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;userAgent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;custom user agent&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;📌 Last level of fallback in execution priority&lt;br&gt;
✅ Works only on active operations&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  🔁 Execution hierarchy summary:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Highest priority] Operation → Hook → All hooks → Global [Lowest priority]

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The more detailed the definition level, the higher the execution priority. This hierarchy provides great flexibility for precise, customized, and targeted logging.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧬 &lt;code&gt;customLogger&lt;/code&gt; structure
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;customLogger&lt;/code&gt; function is the heart of the custom logging mechanism in the &lt;code&gt;payload-auditor&lt;/code&gt; plugin. This function allows you to &lt;strong&gt;edit or generate log fields&lt;/strong&gt; before final logging. To do this, the function takes two inputs and must return a specific output.&lt;/p&gt;

&lt;h3&gt;
  
  
  🛠 Function Inputs
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;customLogger&lt;/code&gt; function has two main inputs:&lt;/p&gt;

&lt;h4&gt;
  
  
  1. &lt;code&gt;args&lt;/code&gt;: All hook arguments
&lt;/h4&gt;

&lt;p&gt;This argument contains complete information about the current hook and the operation that was executed. Typically contains values like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;req&lt;/code&gt;: HTTP request object&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;operation&lt;/code&gt;: Operation type (&lt;code&gt;create&lt;/code&gt;, &lt;code&gt;update&lt;/code&gt;, &lt;code&gt;delete&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;doc&lt;/code&gt;: Final document after modification&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;previousDoc&lt;/code&gt;: Previous document (in update and delete operations)&lt;/li&gt;
&lt;li&gt;Other information depending on the hook type&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  2. &lt;code&gt;fields&lt;/code&gt;: Initial log structure (Log Fields)
&lt;/h4&gt;

&lt;p&gt;This object contains the default log data generated by the plugin, &lt;strong&gt;without fields&lt;/strong&gt; &lt;strong&gt;&lt;code&gt;hook&lt;/code&gt;&lt;/strong&gt;. You can override, modify, or add fields to this object.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;📍Note: If you want to add a new field, you must define that field for the plugin root collection using &lt;code&gt;configureRootCollection&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  📤 Expected Output
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;customLogger&lt;/code&gt; function should return an object that has the following structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nb"&gt;Omit&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;AuditorLog&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hook&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is, it must include all the fields required for logging, except &lt;code&gt;hook&lt;/code&gt; which is automatically added by the plugin.&lt;/p&gt;

&lt;p&gt;📌 &lt;strong&gt;Simple example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="na"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;ip&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;unknown&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ⏳ Support for async operations
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;customLogger&lt;/code&gt; function can also operate &lt;strong&gt;asynchronously (&lt;/strong&gt;***&lt;em&gt;**&lt;code&gt;async&lt;/code&gt;&lt;/em&gt;*  &lt;strong&gt;)&lt;/strong&gt; . That is, you can use async functions such as accessing a database, reading from external APIs or long-running processes and return the final value with &lt;code&gt;await&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;📌 &lt;strong&gt;Example with Promise:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;geoInfo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getGeoInfo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="na"&gt;location&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;geoInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;city&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;🔄 If the function output is of type &lt;code&gt;Promise&lt;/code&gt;, the plugin will automatically resolve it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This flexibility in the &lt;code&gt;customLogger&lt;/code&gt; structure allows you to generate the structure you want for any scenario, from simple logging to the most complex analytics.&lt;/p&gt;




&lt;h2&gt;
  
  
  📌 Practical examples
&lt;/h2&gt;

&lt;p&gt;In this section, we will examine two common examples of &lt;code&gt;customLogger&lt;/code&gt; usage; one simple and the other with async operations. Each example is analyzed line by line to make the practical concepts clear.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. 🧼 Changing the user value to &lt;code&gt;null&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;customLogger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  🧩 Line-by-line analysis
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;customLogger&lt;/code&gt;: is a synchronous function that takes two parameters:&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;args&lt;/code&gt;: information about the operation, such as request, document, etc.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;fields&lt;/code&gt;: raw log data before final processing.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;...fields&lt;/code&gt;: first we keep all the initial fields of the log.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;user: null&lt;/code&gt;: then we manually set the value of &lt;code&gt;user&lt;/code&gt; to &lt;code&gt;null&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  🎯 Real-world uses of this change
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Removal of sensitive information&lt;/strong&gt;: In some scenarios you may not want to record user IDs or information (for example, in anonymous forms).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Anonymization of logs&lt;/strong&gt; for privacy or in test environments.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automated processes&lt;/strong&gt; where no human user is involved and &lt;code&gt;user&lt;/code&gt; is irrelevant.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  2. 🌐 Adding custom information (e.g. IP)
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;📍Note: If you want to add a new field, you must define that field for the plugin root collection using &lt;code&gt;configureRootCollection&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;customLogger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getIPFromRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ip&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  🧩 Line-by-line analysis
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;The function is &lt;code&gt;async&lt;/code&gt; because it uses the &lt;code&gt;await&lt;/code&gt; helper function.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;getIPFromRequest(args.req)&lt;/code&gt;: A hypothetical function to extract the IP from the request.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;...fields&lt;/code&gt;: Preserve the original data.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;meta: { ...fields.meta, ip }&lt;/code&gt;: Add the IP to the log metadata section, without removing the previous metadata.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  🧰 Introducing the helper function
&lt;/h4&gt;

&lt;p&gt;The &lt;code&gt;getIPFromRequest&lt;/code&gt; function can be defined simply as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getIPFromRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;PayloadRequest&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;ip&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;x-forwarded-for&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]?.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;unknown&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;This function first gets the IP from &lt;code&gt;req.ip&lt;/code&gt;, otherwise it uses proxy headers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  🎯 Real-world applications
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Security analysis&lt;/strong&gt;: Detect suspicious situations by examining IP.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recording user behavior&lt;/strong&gt; based on geographic location.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitoring system load&lt;/strong&gt; from specific regions or specific users.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⚠️ Critical points when using &lt;code&gt;customLogger&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;To use &lt;code&gt;customLogger&lt;/code&gt; correctly and effectively in the &lt;code&gt;payload-auditor&lt;/code&gt; plugin, it is crucial to be familiar with some limitations and prioritization behaviors. In this section, we will review the most important critical points:&lt;/p&gt;

&lt;h3&gt;
  
  
  🔄 1. Prioritization when using customLogger
&lt;/h3&gt;

&lt;p&gt;If you have defined &lt;code&gt;customLogger&lt;/code&gt; at different levels (for example, both at the operation level and at the hook or global level), the plugin will always &lt;strong&gt;use the closest definition&lt;/strong&gt;. The order of precedence is as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;customLogger at the operation-level&lt;/strong&gt;
For example:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;customLogger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ Highest priority – will only be executed for that specific operation.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;customLogger at hook level&lt;/strong&gt;
For example:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;afterChange&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;customLogger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ Runs only if the corresponding operation does not have a dedicated customLogger.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;customLogger at the global hooks level&lt;/strong&gt;
For example:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;hooks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;customLogger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ Runs if neither operation-level nor hook-level customLogger exists.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;customLogger at global level (for all collections)&lt;/strong&gt; 
For example:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;auditor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;customLogger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ Finally, the final fallback; runs only if no other level has a customLogger.&lt;/p&gt;

&lt;h3&gt;
  
  
  🧩 2. Differences with &lt;code&gt;customLogger&lt;/code&gt; at hook level
&lt;/h3&gt;

&lt;p&gt;There are important differences between &lt;code&gt;customLogger&lt;/code&gt; at hook level (e.g. &lt;code&gt;afterChange&lt;/code&gt;) and operation level:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;customLogger (operation)&lt;/th&gt;
&lt;th&gt;customLogger (hook-level)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Dependent on operation type&lt;/td&gt;
&lt;td&gt;For any operation you have defined&lt;/td&gt;
&lt;td&gt;Yes, but only when not defined&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scope of effect&lt;/td&gt;
&lt;td&gt;A specific operation&lt;/td&gt;
&lt;td&gt;All operations related to that hook&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Execution priority&lt;/td&gt;
&lt;td&gt;Higher&lt;/td&gt;
&lt;td&gt;Lower than operation level&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ It is important not to confuse these two levels, as you might think your customLogger is running, but because there is a more precise version at a lower level, it is not called at all.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  ✅ Best Practices
&lt;/h2&gt;

&lt;p&gt;To make your logging system both fast and secure, it is very important to follow a few key principles in the design and implementation of &lt;code&gt;customLogger&lt;/code&gt;. In this section, we will discuss recommendations that will both improve the developer experience and make the system easier to maintain:&lt;/p&gt;

&lt;h3&gt;
  
  
  🧼 1. Keep your log structure simple
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Minimalism&lt;/strong&gt; in logging helps reduce data volume and storage costs.&lt;/li&gt;
&lt;li&gt;Avoid adding unnecessary or nested fields.&lt;/li&gt;
&lt;li&gt;Always design logs for fast processing in analytics systems (like ELK, Datadog, or Logstash).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;✅ &lt;strong&gt;Good example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;create&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;❌ &lt;strong&gt;Bad example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="na"&gt;debugDump&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="na"&gt;requestHeaders&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="na"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;span class="na"&gt;callStack&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  🔐 2. Avoid storing sensitive data (unless encrypted)
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;📍Note: The plugin itself may store email in raw form in the logs. It is the developer's responsibility to use encryption to store sensitive data&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Avoid storing private user data such as email, IP, or phone number in raw form.&lt;/li&gt;
&lt;li&gt;If you need to store this data, use encryption or hashing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;✅ &lt;strong&gt;Suggested example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="na"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="na"&gt;emailHash&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;sha256&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🌐 3. Use async for external data
&lt;/h3&gt;

&lt;p&gt;If you need to get data from external sources (such as IP location, browser information, or external validations), &lt;code&gt;customLogger&lt;/code&gt; fully supports &lt;code&gt;async&lt;/code&gt; functions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: Adding user location from IP&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;customLogger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;location&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getGeoLocation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="na"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;📌 &lt;strong&gt;Note:&lt;/strong&gt;  If you use external resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pay attention to API latency.&lt;/li&gt;
&lt;li&gt;Consider caching or rate-limiting.&lt;/li&gt;
&lt;li&gt;Use appropriate timeouts so that the entire log process does not break.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🎯 Other recommendations
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use collections for testing &lt;code&gt;customLogger&lt;/code&gt; whose changes are less critical.&lt;/li&gt;
&lt;li&gt;Do not use &lt;code&gt;customLogger&lt;/code&gt; to modify the original data (it is only for creating logs).&lt;/li&gt;
&lt;li&gt;If you need a different customLogger based on the user type, you can put a condition in it:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;admin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;severity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;high&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  📍 Conclusion
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;customLogger&lt;/code&gt; feature in the &lt;code&gt;payload-auditor&lt;/code&gt; plugin is a very powerful tool for customizing the logging process in Payload CMS-based projects. This feature allows you to precisely and with full control, tailor the content of the logs to your project's security, analytical, and operational needs.&lt;/p&gt;

&lt;h3&gt;
  
  
  🧩 Summary of features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;High flexibility&lt;/strong&gt; at four levels: operation level, hook, hooks-level and global&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ability to process synchronously and asynchronously (async)&lt;/strong&gt;  in log generation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Support for external data&lt;/strong&gt; such as IP, geolocation or user role&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ability to filter, modify, or remove sensitive information&lt;/strong&gt; before saving&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🎯 More accurate tracking of system changes
&lt;/h3&gt;

&lt;p&gt;By using &lt;code&gt;customLogger&lt;/code&gt; wisely, you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Record and analyze specific changes based on user context&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Generate targeted and actionable logs&lt;/strong&gt; that are valuable for monitoring and security tools&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Make the debugging process&lt;/strong&gt; faster and more accurate for the development team&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  💡 Suggestions for developers
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;customLogger&lt;/code&gt; to &lt;strong&gt;build a reliable logging infrastructure&lt;/strong&gt; alongside other observability tools like Sentry Or use Grafana.&lt;/li&gt;
&lt;li&gt;For projects with high security requirements, be sure to &lt;strong&gt;encrypt sensitive data&lt;/strong&gt; in logs.&lt;/li&gt;
&lt;li&gt;Use async loggers to &lt;strong&gt;balance system performance with log richness.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ultimately, &lt;code&gt;customLogger&lt;/code&gt; is not just an optional feature, but can be a key part of your audit and security strategy. If used correctly, it can be the difference between a purely decorative log and a real analysis and response tool.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔗 Link to the main plugin documentation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/shaadcode/payload-auditor#readme" rel="noopener noreferrer"&gt;Official documentation &lt;/a&gt;&lt;a href="https://github.com/shaadcode/payload-auditor#readme" rel="noopener noreferrer"&gt;&lt;code&gt;payload-auditor&lt;/code&gt;&lt;/a&gt;
Includes a full explanation of options, log structure, logging levels, and practical examples.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  💻 GitHub Repository Link
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;GitHub Repository:
👉 &lt;a href="https://github.com/shaadcode/payload-auditor" rel="noopener noreferrer"&gt;https://github.com/shaadcode/payload-auditor&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this repo you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;View and install the latest version of the plugin&lt;/li&gt;
&lt;li&gt;Track Issues and Feature Requests&lt;/li&gt;
&lt;li&gt;Contribute to the plugin development&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  🤝 Appreciation and Contribution
&lt;/h4&gt;

&lt;p&gt;If you found this plugin useful or this article helped you understand it better, please support me by giving the &lt;a href="https://github.com/shaadcode/payload-auditor" rel="noopener noreferrer"&gt;payload-auditor&lt;/a&gt; repo a ⭐️. This motivates me to develop more open source tools.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🙏 Thank you for your support!&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>webdev</category>
      <category>nextjs</category>
      <category>react</category>
      <category>security</category>
    </item>
    <item>
      <title>Tracking and Security in Payload CMS with the Payload-Auditor Plugin</title>
      <dc:creator>seyed mojtaba shadab</dc:creator>
      <pubDate>Sat, 24 May 2025 05:32:37 +0000</pubDate>
      <link>https://dev.to/shaadcode/tracking-and-security-in-payload-cms-with-the-payload-auditor-plugin-mpk</link>
      <guid>https://dev.to/shaadcode/tracking-and-security-in-payload-cms-with-the-payload-auditor-plugin-mpk</guid>
      <description>&lt;p&gt;Before we get into the main topic of the article, let's first learn about Payload CMS.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Brief Introduction to Payload CMS
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Payload CMS&lt;/strong&gt; is a modern, fully JavaScript-based, headless content management system. Unlike many traditional CMSs, Payload has a strong focus on &lt;strong&gt;customization, high performance, and a developer-centric experience&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of using pre-built panels, it allows you to fully define the structure and behavior of your admin panel through code. Some of its notable features include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Full support for &lt;strong&gt;TypeScript&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced system for defining &lt;strong&gt;collections and fields&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ability to add &lt;strong&gt;hooks and detailed access control&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Headless design for use in separate &lt;strong&gt;Frontend projects (React, Next.js, Vue, etc.)&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;And strong support for &lt;strong&gt;authentication, file upload, and REST and GraphQL APIs&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Overall, Payload CMS is a powerful option for developers who want full control over the structure and functionality of their CMS — without having to deal with the limitations of traditional platforms.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why do we need logging and tracing in Payload?
&lt;/h3&gt;

&lt;p&gt;In the world of modern software, especially in projects built with headless CMSs like &lt;strong&gt;Payload CMS&lt;/strong&gt;, the issue of &lt;strong&gt;security, transparency, and user behavior analysis&lt;/strong&gt; is of utmost importance.&lt;/p&gt;

&lt;p&gt;As the scale of the project grows and the number of users or administrators increases, knowing &lt;strong&gt;who did what, when, and where&lt;/strong&gt; is no longer an optional feature — it is a &lt;strong&gt;vital need&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Here are some reasons why logging and tracing is necessary:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🧑‍💻 &lt;strong&gt;Track user actions&lt;/strong&gt;: Who changed the information? When was a file deleted? Did someone log in with the wrong access?&lt;/li&gt;
&lt;li&gt;🛡️ &lt;strong&gt;Increase security&lt;/strong&gt;: Recording suspicious or sensitive events (such as changes to user information or suspicious logins) is the first line of defense against attacks.&lt;/li&gt;
&lt;li&gt;🧾 &lt;strong&gt;Organizational Transparency&lt;/strong&gt;: In multi-person teams, knowing the history of actions prevents repetitive errors and creates order in team processes.&lt;/li&gt;
&lt;li&gt;🧪 &lt;strong&gt;Debugging and analyzing system behavior&lt;/strong&gt;: Having a history of operations is very helpful when developing or investigating problems.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Payload Auditor Plugin: Answering Your Monitoring and Security Needs
&lt;/h3&gt;

&lt;p&gt;This is where the &lt;strong&gt;Payload Auditor&lt;/strong&gt; plugin comes in. It is designed to work seamlessly with Payload CMS, allowing for &lt;strong&gt;detailed logging of operations, event tracking, and greater control over&lt;/strong&gt; backend security.&lt;/p&gt;

&lt;p&gt;Not only does the plugin allow you to specify which collections to track, but you can even fine-tune the &lt;strong&gt;type of operation (create, update, delete)&lt;/strong&gt;  per hook. Simply put, you have complete control over what gets logged — without any added overhead or unnecessary complexity.&lt;/p&gt;

&lt;p&gt;I’ll give you a more complete explanation later.&lt;/p&gt;




&lt;h3&gt;
  
  
  Why Payload Auditor?
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Common Problems in Payload Projects Without a Logging System
&lt;/h4&gt;

&lt;p&gt;In many projects built with &lt;strong&gt;Payload CMS&lt;/strong&gt;, developers focus primarily on data structure, admin panel design, and API interaction — but an important part that is often overlooked is &lt;strong&gt;the logging and event monitoring system&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Here are some common problems that arise in the absence of a proper logging system:&lt;/p&gt;




&lt;p&gt;🔍 &lt;strong&gt;Lack of Clear Change View&lt;/strong&gt;&lt;br&gt;
In projects with multiple content managers or developers, it is often unclear who made what changes and when. This can lead to confusion, repeated errors, or even damage to important data.&lt;/p&gt;



&lt;p&gt;🛠️ &lt;strong&gt;Difficult Debugging&lt;/strong&gt;&lt;br&gt;
In the event of a problem, the lack of detailed reporting of the operations performed causes the development team to spend a lot of time searching through data or code to understand what happened.&lt;/p&gt;



&lt;p&gt;🛡️ &lt;strong&gt;High Security Risks&lt;/strong&gt;&lt;br&gt;
When no traces of sensitive operations (such as updating user information or deleting data) remain, it becomes very difficult to identify suspicious actions or possible abuses.&lt;/p&gt;



&lt;p&gt;📉 &lt;strong&gt;Lack of internal documentation of system performance&lt;/strong&gt;&lt;br&gt;
In organizational or team projects, automated documentation of user and system behavior plays a vital role in analyzing and improving processes. Otherwise, this task is either completely forgotten or performed manually and incompletely.&lt;/p&gt;



&lt;p&gt;⏸️ &lt;strong&gt;Lack of tracking and targeted stopping of operations&lt;/strong&gt;&lt;br&gt;
Without a monitoring system, it is not possible to centrally specify whether logging should be stopped in a specific section or only certain operations (such as creation or deletion) should be logged.&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;Payload Auditor&lt;/strong&gt; fills these gaps — as a simple, flexible, and powerful tool for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tracking all important activities&lt;/li&gt;
&lt;li&gt;Accurately recording the history of operations&lt;/li&gt;
&lt;li&gt;Controlling access to logs&lt;/li&gt;
&lt;li&gt;and increasing the overall security of your project&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Benefits of Using the Payload Auditor Plugin
&lt;/h3&gt;

&lt;p&gt;Using the &lt;strong&gt;Payload Auditor&lt;/strong&gt; plugin allows developers to make their projects more professional, secure, and more analyzable. Here are the most important benefits of this tool:&lt;/p&gt;



&lt;p&gt;✅ &lt;strong&gt;Full Activity Tracking&lt;/strong&gt;&lt;br&gt;
This plugin allows for accurate recording of operations such as user creation, editing, deletion, and login. You can know who did what, when, and what — something that is practically impossible in systems without logging.&lt;/p&gt;



&lt;p&gt;🔐 &lt;strong&gt;More security in multi-user environments&lt;/strong&gt;&lt;br&gt;
In projects where multiple users with different access levels are working, tracking and limiting access to logs plays an important role in preventing abuse or unwanted changes. This plugin allows you to control access to reports and closely monitor activities.&lt;/p&gt;



&lt;p&gt;🏢 &lt;strong&gt;Suitable for SaaS and Enterprise Projects&lt;/strong&gt;&lt;br&gt;
In SaaS and Enterprise-level projects, detailed reports, change history, and analytical tools are a must. By providing these features, Payload Auditor helps you build a professional, reliable, and industry-standard product.&lt;/p&gt;



&lt;p&gt;⚙️ &lt;strong&gt;High customization for specific needs&lt;/strong&gt;&lt;br&gt;
Through flexible settings, this plugin allows you to track only the collections that are important to you, select the type of operations, and even disable its functionality in certain situations.&lt;/p&gt;



&lt;p&gt;📊 &lt;strong&gt;Analysis of behavioral and operational data&lt;/strong&gt;&lt;br&gt;
By recording structured events, you can perform valuable analyses on user behavior, system problems, or usage patterns in the future. This information can be useful in optimizing the user experience or making management decisions.&lt;/p&gt;
&lt;h3&gt;
  
  
  Install and set up the Payload Auditor plugin
&lt;/h3&gt;

&lt;p&gt;Setting up the &lt;code&gt;payload-auditor&lt;/code&gt; plugin is very simple and quick, and it can be added to the Payload CMS project in a few short steps. Here are the basic installation and configuration steps:&lt;/p&gt;


&lt;h4&gt;
  
  
  🧱 Installing with npm / yarn / pnpm
&lt;/h4&gt;

&lt;p&gt;First, add the plugin to your project using your preferred package manager (although we recommend using pnpm):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;payload-auditor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or if you are using &lt;code&gt;yarn&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add payload-auditor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or with &lt;code&gt;pnpm&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm add payload-auditor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h4&gt;
  
  
  ⚙️ Adding the plugin to the Payload configuration
&lt;/h4&gt;

&lt;p&gt;After installation, simply import and enable the plugin in the Payload configuration file (usually &lt;code&gt;payload.config.ts&lt;/code&gt; or &lt;code&gt;payload.config.js&lt;/code&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;buildConfig&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;payload/config&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;auditorPlugin&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;payload-auditor&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;buildConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;collections&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="c1"&gt;// ... your collections here&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nf"&gt;auditorPlugin&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="c1"&gt;// plugin settings go here&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h4&gt;
  
  
  🛠️ Basic configuration (simple example)
&lt;/h4&gt;

&lt;p&gt;In this simple example, we will configure only one collection called &lt;code&gt;media&lt;/code&gt; for logging. Payload-Auditor uses payload cms hooks for logging operations. In this configuration, only &lt;code&gt;update&lt;/code&gt; operations will be logged using the afterChange hook:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;auditorPlugin&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;trackCollections&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;media&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;hooks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;afterChange&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;update&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With these simple settings, the plugin starts logging changes to the &lt;code&gt;media&lt;/code&gt; collection.&lt;/p&gt;

&lt;h3&gt;
  
  
  Payload Auditor Plugin Configuration Options
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;payload-auditor&lt;/code&gt; plugin is designed for high flexibility, allowing you to specify exactly &lt;strong&gt;which collections are logged, under what conditions, and with what operations&lt;/strong&gt;. Here are the most important configuration options:&lt;/p&gt;

&lt;h4&gt;
  
  
  🕒 &lt;code&gt;automation&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;This option manages automated operations in the logging system. For example, you can specify how many old logs you want to delete. You can even specify which logs are considered old:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;      &lt;span class="nx"&gt;automation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;logCleanup&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;strategy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;manual&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;66&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;olderThan&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2m&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above code, logs that are more than two minutes old are considered old and 66 of them are deleted each time. Please note that this is just an example.&lt;/p&gt;

&lt;h4&gt;
  
  
  📁 &lt;code&gt;trackCollections&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;In this option, you introduce a list of collections whose activities you want to track. For each collection you can have its own settings. The settings in this section are very flexible, meaning you can enable all Payload hooks for each collection and even specify which operations you want to enable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;trackCollections&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;users&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;hooks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;afterChange&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;update&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h4&gt;
  
  
  🎯 Filtering operations inside hooks
&lt;/h4&gt;

&lt;p&gt;The plugin allows you to log &lt;strong&gt;only some specific operations&lt;/strong&gt; (for example, only &lt;code&gt;update&lt;/code&gt; or &lt;code&gt;delete&lt;/code&gt;).&lt;br&gt;
This way, the logs become more targeted and lightweight.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;hooks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;afterOperation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  📦 Complete example of an advanced configuration
&lt;/h3&gt;

&lt;p&gt;In the following example, two collections (&lt;code&gt;users&lt;/code&gt; and &lt;code&gt;posts&lt;/code&gt;) are tracked. In the &lt;code&gt;users&lt;/code&gt; collection, only the &lt;code&gt;update&lt;/code&gt; operation is logged in the &lt;code&gt;afterChange&lt;/code&gt; hook. In the &lt;code&gt;posts&lt;/code&gt; collection, only the &lt;code&gt;delete&lt;/code&gt; is logged in the &lt;code&gt;afterOperation&lt;/code&gt; hook. Also, the logs are deleted after 30 days:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;auditorPlugin&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;automation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;logCleanup&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;strategy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;manual&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;olderThan&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;7d&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;trackCollections&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;users&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;hooks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="na"&gt;afterChange&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;update&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                  &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
              &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;posts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;hooks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="na"&gt;afterOperation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                  &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
              &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  How the Payload Auditor Plugin Works
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;payload-auditor&lt;/code&gt; plugin uses the very powerful &lt;strong&gt;hooks feature of Payload CMS&lt;/strong&gt; to log and track important operations at the collection level. This approach makes logging non-destructive, modular, and controllable.&lt;/p&gt;




&lt;h4&gt;
  
  
  🔄 Using hooks for logging
&lt;/h4&gt;

&lt;p&gt;By default, Payload CMS provides a set of &lt;strong&gt;hooks for each collection&lt;/strong&gt;, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;beforeChange&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;afterChange&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;beforeOperation&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;afterOperation&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;and all payload cms hooks...&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By connecting to these hooks, the &lt;code&gt;payload-auditor&lt;/code&gt; plugin intercepts and logs all operations that occur in your project — but only if you have enabled it.&lt;/p&gt;

&lt;p&gt;📌 Unlike some other tools, this plugin &lt;strong&gt;only logs when you tell it to&lt;/strong&gt;, so there is no additional overhead to your project.&lt;/p&gt;




&lt;h4&gt;
  
  
  ⚙️ Differences between operations (create, update, delete)
&lt;/h4&gt;

&lt;p&gt;For each hook you can specify exactly which type of operation should be logged. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;hooks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;beforeValidate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;update&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;update&lt;/code&gt; operation is logged in the &lt;code&gt;afterChange&lt;/code&gt; hook.&lt;/li&gt;
&lt;li&gt;But the &lt;code&gt;create&lt;/code&gt; operation is ignored. Of course, it is also ignored if you do not fully define this operation. This feature is mostly for when you want to ignore this operation for now and enable it later.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This level of &lt;strong&gt;fine-grained control&lt;/strong&gt; allows you to tailor the logging system to exactly the needs of your project.&lt;/p&gt;




&lt;h4&gt;
  
  
  ⏸️ Ability to temporarily stop logging for a specific collection
&lt;/h4&gt;

&lt;p&gt;You may want to temporarily stop logging on a collection — for example, to fix a bug or during development. The plugin provides this feature as well. Just set the &lt;code&gt;enabled&lt;/code&gt; property value to &lt;code&gt;false&lt;/code&gt; or remove the collection from the &lt;code&gt;trackCollections&lt;/code&gt; list.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;comments&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// This collection is temporarily untracked.&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or remove it altogether so that no hooks are attached to it.&lt;/p&gt;

&lt;p&gt;This design is &lt;strong&gt;both simple and extensible&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Usage Scenarios
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;payload-auditor&lt;/code&gt; plugin is not just a logging tool; it is a tool for &lt;strong&gt;analysis, security, and better management of real projects&lt;/strong&gt;. Here are some of the most common scenarios where this plugin will be very useful:&lt;/p&gt;

&lt;h4&gt;
  
  
  🔐 Logging user logins and profile changes
&lt;/h4&gt;

&lt;p&gt;In projects where users can log into the admin panel, accurate tracking of when and how they log in or changes to their profile is very important from a security and support perspective.&lt;/p&gt;

&lt;p&gt;By enabling logging on the &lt;code&gt;users&lt;/code&gt; collection (assuming that site users are stored in a collection with the slug users), you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Identify who logged in and when.&lt;/li&gt;
&lt;li&gt;Document changes to email, name, password, or user role.&lt;/li&gt;
&lt;li&gt;Track support reports faster.&lt;/li&gt;
&lt;/ul&gt;




&lt;h4&gt;
  
  
  🔍 Security Issues Investigation and User Behavior Analysis
&lt;/h4&gt;

&lt;p&gt;In many cases, suspicious behavior or security issues can be identified simply by looking at the logs. This plugin allows you to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Track unusual deletion or editing operations.&lt;/li&gt;
&lt;li&gt;Analyze specific user or admin behaviors and identify dangerous patterns.&lt;/li&gt;
&lt;li&gt;Generate a detailed report for security or compliance audits (in development).&lt;/li&gt;
&lt;/ul&gt;




&lt;h4&gt;
  
  
  👥 Use in multi-user projects with different access levels
&lt;/h4&gt;

&lt;p&gt;In projects where several people with different roles work on a CMS, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Content Editors&lt;/li&gt;
&lt;li&gt;Support Agents&lt;/li&gt;
&lt;li&gt;Admins&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Managing changes and answering the question "Who did what?" becomes extremely difficult.&lt;br&gt;
The &lt;code&gt;payload-auditor&lt;/code&gt; plugin is essential in such environments:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Accurately logging operations for each role&lt;/li&gt;
&lt;li&gt;Preventing unwanted or erroneous changes&lt;/li&gt;
&lt;li&gt;Helping to build team discipline and trust in large teams&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Best practices for using Payload Auditor
&lt;/h3&gt;

&lt;p&gt;To use the &lt;code&gt;payload-auditor&lt;/code&gt; plugin effectively and securely, it is recommended to follow some tips and recommendations. Here are some important ones:&lt;/p&gt;


&lt;h4&gt;
  
  
  ✅ 1. Optimal and targeted configuration
&lt;/h4&gt;

&lt;p&gt;Not all collections need logging. Only select those that contain sensitive data or important operations (such as &lt;code&gt;users&lt;/code&gt;, &lt;code&gt;orders&lt;/code&gt;, &lt;code&gt;payments&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recommendation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Only enable hooks and operations that really need to be tracked.&lt;/li&gt;
&lt;li&gt;This will reduce the size of the logs and improve system performance.&lt;/li&gt;
&lt;/ul&gt;


&lt;h4&gt;
  
  
  🧹 2. Intelligent long-term log retention
&lt;/h4&gt;

&lt;p&gt;If not managed properly, logs can cause database size to increase and performance to decrease over time. Use the &lt;code&gt;automation&lt;/code&gt; option to control the lifetime of logs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt; &lt;span class="nx"&gt;automation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;//  ...&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;In sensitive projects&lt;/strong&gt;:&lt;br&gt;
If you need long-term retention, move logs to archive systems or centralized logging tools (like ELK Stack or Logstash). For this, you can use customLogger which is provided at 4 levels: global, hook level, specific hook level and operation level.&lt;/p&gt;


&lt;h4&gt;
  
  
  🔒 3. Restrict access to logs
&lt;/h4&gt;

&lt;p&gt;Not all users should have access to logs. For added security:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Only root admins or users with specific roles (e.g. &lt;code&gt;Auditor&lt;/code&gt;) should be able to view or analyze logs.&lt;/li&gt;
&lt;li&gt;Restrict access to log collections using &lt;strong&gt;Access Control in Payload&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Simple example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;Accessibility&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
          &lt;span class="c1"&gt;// Your configuration&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h4&gt;
  
  
  🧪 4. Testing and Monitoring in the Development Environment
&lt;/h4&gt;

&lt;p&gt;Before using in the production environment, test the plugin’s performance thoroughly in the development or staging environment. Check:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Are logs recorded accurately?&lt;/li&gt;
&lt;li&gt;Are unnecessary operations not logged?&lt;/li&gt;
&lt;li&gt;Is system performance not degraded?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Following these practices will make the Payload Auditor plugin one of the pillars of your project’s security and professional maintenance, rather than an additional tool.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;Payload Auditor&lt;/strong&gt; plugin is a powerful and flexible tool that allows you to accurately and securely track user activities and important changes in your Payload CMS projects. With this plugin, you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Increase project security in multi-user environments,&lt;/li&gt;
&lt;li&gt;Quickly identify problems and suspicious behavior,&lt;/li&gt;
&lt;li&gt;Generate detailed and analytical reports for better project management,&lt;/li&gt;
&lt;li&gt;And experience all these features with high customization capabilities and precise log management.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are also looking to improve security and transparency in your Payload CMS projects, we recommend that you definitely try this plugin.&lt;/p&gt;




&lt;h3&gt;
  
  
  Contribute to development
&lt;/h3&gt;

&lt;p&gt;This project is open source and interested developers can help improve and expand it by providing feedback, suggestions, or contributing to its development. To view the source code, complete documentation, and start contributing, visit its official GitHub repository:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/shaadcode/payload-auditor" rel="noopener noreferrer"&gt;Payload Auditor on GitHub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With this tool, take an important step towards increasing the security, control, and monitoring of your Payload CMS projects and experience more sustainable development.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resources and Links
&lt;/h3&gt;

&lt;p&gt;To learn more and better use the Payload Auditor plugin, as well as learn related concepts, you can refer to the following resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://github.com/shaadcode/payload-auditor" rel="noopener noreferrer"&gt;Official Payload Auditor Repository on GitHub&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://payloadcms.com/docs/" rel="noopener noreferrer"&gt;Official Payload CMS Documentation&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;If you’re looking to increase security, transparency, and analytics in your Payload CMS projects, try the Payload Auditor plugin today.&lt;br&gt;
We’re eager to hear your feedback, suggestions, and contributions to the development of this tool.&lt;br&gt;
Check out the project on GitHub, give it a ⭐ star, and join us in building a stronger and more secure Payload ecosystem!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>nextjs</category>
      <category>react</category>
      <category>security</category>
    </item>
  </channel>
</rss>
