@@ -37,6 +37,12 @@ rotation with gzip compression.
3737composer require mrnaeem4/ci3-request-analysis
3838```
3939
40+ > ** Custom ` vendor-dir ` :** If your ` composer.json ` sets ` "vendor-dir" `
41+ > (e.g. ` application/third_party/vendor ` ), the package installs there. That is
42+ > fine — just point ` $config['composer_autoload'] ` at that exact
43+ > ` vendor/autoload.php ` path. CodeIgniter's ` TRUE ` shortcut only looks at
44+ > ` application/vendor/ ` and the project root.
45+
4046If you do not use Composer, add a PSR-4 autoloader mapping
4147` MrNaeem\Ci3RequestAnalysis\ ` to the ` src/ ` directory, or require the three
4248classes manually:
@@ -60,21 +66,62 @@ $config['composer_autoload'] = TRUE; // or absolute path to vendor/autoload.php
6066
6167### 2. Register the hook
6268
69+ > ** Important:** CI3's array hook format (` class ` /` function ` /` filename ` /
70+ > ` filepath ` ) cannot resolve Composer namespaced classes — ` CI_Hooks::_run_hook() `
71+ > checks ` class_exists($class, false) ` (no autoload) and then ` require_once ` s
72+ > the ` filepath ` /` filename ` , which fails for vendor files. Use a ** closure**
73+ > instead (CI3 supports callables natively):
74+
6375In ` application/config/hooks.php ` :
6476
6577``` php
66- $hook['post_controller_constructor'] = [
67- 'class' => 'MrNaeem\Ci3RequestAnalysis\Hooks\RequestLogHook',
68- 'function' => 'before',
69- 'filename' => '',
70- 'filepath' => '',
71- 'params' => [],
72- ];
78+ $hook['post_controller_constructor'] = function () {
79+ (new \MrNaeem\Ci3RequestAnalysis\Hooks\RequestLogHook())->before();
80+ };
81+ ```
82+
83+ ### 3. Load the ` .env ` file
84+
85+ CI3 does ** not** parse a ` .env ` file by itself, and the config values are read
86+ with ` getenv() ` . Without loading the file, ` REQUEST_LOG_ENABLED ` is empty and
87+ the hook silently does nothing. Pick one:
88+
89+ ** Option A — vlucas/phpdotenv (recommended):**
90+
91+ ``` bash
92+ composer require vlucas/phpdotenv
93+ ```
94+
95+ Load it in ` index.php ` (the front controller) ** before** requiring
96+ ` CodeIgniter.php ` :
97+
98+ ``` php
99+ require_once FCPATH . 'vendor/autoload.php';
100+
101+ $dotenv = Dotenv\Dotenv::createUnsafeImmutable(FCPATH);
102+ $dotenv->safeLoad();
103+ ```
104+
105+ ** Option B — Apache ` SetEnv ` :**
106+
107+ ``` apache
108+ # .htaccess
109+ SetEnv REQUEST_LOG_ENABLED true
110+ SetEnv REQUEST_LOG_REDACT_FIELDS "password,nik,Cookie,Api-Key,no_telp"
111+ ```
112+
113+ ** Option C — Nginx ` fastcgi_param ` :**
114+
115+ ``` nginx
116+ location ~ \.php$ {
117+ fastcgi_param REQUEST_LOG_ENABLED true;
118+ # ...
119+ }
73120```
74121
75- ### 3 . Set environment variables
122+ ### 4 . Set environment variables
76123
77- Set in your web server environment or system environment :
124+ Values of the ` .env ` file ( or server env) :
78125
79126``` ini
80127REQUEST_LOG_ENABLED = true
@@ -85,6 +132,9 @@ REQUEST_LOG_MAX_BODY_SIZE = 3145728
85132REQUEST_LOG_WHITELIST_IPS = " 10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,127.0.0.1"
86133REQUEST_LOG_TRUNCATE_SUFFIX = " ... [truncated]"
87134REQUEST_LOG_RETENTION_DAYS = 30
135+ REQUEST_LOG_METHODS = " " # empty = log all; e.g. "POST,PUT,DELETE"
136+ REQUEST_LOG_INCLUDE_PATHS = " " # empty = log all; regex, e.g. "^/api/"
137+ REQUEST_LOG_EXCLUDE_PATHS = " " # regex, e.g. "^/assets/,^/health$"
88138```
89139
90140### Config reference
@@ -99,6 +149,24 @@ REQUEST_LOG_RETENTION_DAYS = 30
99149| ` REQUEST_LOG_WHITELIST_IPS ` | RFC1918 + localhost | CIDR ranges to skip. |
100150| ` REQUEST_LOG_TRUNCATE_SUFFIX ` | ` ... [truncated] ` | Appended when the body is truncated. |
101151| ` REQUEST_LOG_RETENTION_DAYS ` | ` 30 ` | Days of compressed logs kept before pruning. |
152+ | ` REQUEST_LOG_METHODS ` | ` '' ` (all) | Comma-separated HTTP methods to log (e.g. ` POST,PUT ` ). |
153+ | ` REQUEST_LOG_INCLUDE_PATHS ` | ` '' ` (all) | Regex allow-list for request paths (comma-separated). |
154+ | ` REQUEST_LOG_EXCLUDE_PATHS ` | ` '' ` (none) | Regex deny-list for request paths (comma-separated). |
155+
156+ ### Path & method filtering
157+
158+ By default ** every** request (including ` GET / ` ) is logged. Restrict it:
159+
160+ ``` ini
161+ # Only mutating requests, only under /api/, never static assets or health checks
162+ REQUEST_LOG_METHODS = " POST,PUT,PATCH,DELETE"
163+ REQUEST_LOG_INCLUDE_PATHS = " ^/api/"
164+ REQUEST_LOG_EXCLUDE_PATHS = " ^/api/assets/,^/api/health$"
165+ ```
166+
167+ Patterns are regex matched against the request path (e.g. ` /api/upload ` ).
168+ ` includePaths ` is evaluated first; a request must match at least one include
169+ pattern when that list is non-empty. ` excludePaths ` wins afterwards.
102170
103171## Log payload
104172
@@ -141,6 +209,7 @@ Each line in `analysis.log` is a JSON object (envelope + `log_data`):
141209Request → CI3 Hook (post_controller_constructor)
142210 ├─ enabled? ──no──► done
143211 ├─ IP whitelisted? ──yes──► done
212+ ├─ method/path filter passes? ──no──► done
144213 ├─ collect: headers, body, files, tenant, srcip...
145214 │ ├─ redact sensitive fields (headers + body)
146215 │ ├─ truncate body at max size
@@ -229,10 +298,9 @@ also rejects `*.log` / `*.gz` matches even if directory-level rules are ignored.
229298
230299## Notes
231300
232- - The hook runs on every request once enabled. To log only specific
233- controllers, guard inside your controller or move the hook logic into a
234- base-controller ` __construct() ` call — see
235- ` sample/application/controllers/Home.php ` for a self-contained demo.
301+ - By default every request is logged (including ` GET / ` ). Use
302+ ` REQUEST_LOG_METHODS ` / ` REQUEST_LOG_INCLUDE_PATHS ` / ` REQUEST_LOG_EXCLUDE_PATHS `
303+ to narrow it down — see * Path & method filtering* above.
236304- Binary file content is never stored; only metadata is captured.
237305- Redaction applies to both request headers (e.g. ` Cookie ` ) and the body.
238306- ` application/logs ` should not be publicly accessible.
0 commit comments