{"id":43678949,"url":"https://github.com/zosconnect/sample-fslogger-interceptor","last_synced_at":"2026-02-05T01:30:29.945Z","repository":{"id":335310153,"uuid":"1142346838","full_name":"zosconnect/sample-fslogger-interceptor","owner":"zosconnect","description":"A sample z/OS Connect interceptor that captures API provider and API requester data and writes it in a JSON format to a log file on the file system.","archived":false,"fork":false,"pushed_at":"2026-01-29T14:42:17.000Z","size":45,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-30T03:54:58.688Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zosconnect.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-26T09:37:52.000Z","updated_at":"2026-01-29T14:42:17.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/zosconnect/sample-fslogger-interceptor","commit_stats":null,"previous_names":["zosconnect/sample-fslogger-interceptor"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/zosconnect/sample-fslogger-interceptor","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zosconnect%2Fsample-fslogger-interceptor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zosconnect%2Fsample-fslogger-interceptor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zosconnect%2Fsample-fslogger-interceptor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zosconnect%2Fsample-fslogger-interceptor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zosconnect","download_url":"https://codeload.github.com/zosconnect/sample-fslogger-interceptor/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zosconnect%2Fsample-fslogger-interceptor/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29105530,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-05T00:52:08.035Z","status":"ssl_error","status_checked_at":"2026-02-05T00:52:07.703Z","response_time":62,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-02-05T01:30:29.022Z","updated_at":"2026-02-05T01:30:29.936Z","avatar_url":"https://github.com/zosconnect.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# z/OS Connect File System Logger Interceptor\n\nA sample z/OS Connect interceptor that captures API provider and API requester data and writes it in a JSON format to a log file on the file system.\n\n## Overview\n\nThis interceptor sample provides comprehensive logging capabilities for z/OS Connect, capturing:\n- Request and response headers\n- Request and response bodies (optional)\n- Request and response sizes (in bytes)\n- Query strings\n- System of Record (SoR) details for API provider\n- API endpoint details for API requester\n- HTTP status codes\n\nThe interceptor writes structured JSON log entries to rolling log files with configurable size and retention limits.\n\n## Features\n\n- **Dual Interceptor Support**: Separate interceptors for API provider and API requester\n- **Rolling File Logs**: Automatic log rotation based on file size\n- **Configurable Retention**: Control maximum number of log files to retain\n- **JSON Format**: Structured log entries in JSON format for easy parsing\n- **Optional Body Logging**: Enable/disable request and response body logging\n- **Thread-Safe**: Safe for concurrent use across multiple APIs and API requesters\n- **Minimal Dependencies**: No external JSON libraries required\n\n## Project Structure\n\n```\nsample-fslogger-interceptor/\n├── build.gradle                                       # Root Gradle build file\n├── settings.gradle                                    # Gradle settings\n├── com.ibm.sample.zosconnect.fslogger.interceptor/    # OSGi Bundle\n│   ├── build.gradle                                    # Interceptor module build\n│   ├── src/\n│   │   └── com/ibm/sample/zosconnect/fslogger/\n│   │       ├── common/                                 # Shared utilities\n│   │       │   └── RollingFileHandler.java\n│   │       ├── provider/                               # API provider interceptor\n│   │       │   ├── FileSystemLoggerProviderInterceptor.java\n│   │       │   └── LogEntryProvider.java\n│   │       └── requester/                              # API requester interceptor\n│   │           ├── FileSystemLoggerRequesterInterceptor.java\n│   │           └── LogEntryRequester.java\n│   └── BundleContent/\n│       ├── META-INF/\n│       │   └── MANIFEST.MF\n│       └── OSGI-INF/\n│           ├── metatype/\n│           │   └── metatype.xml\n│           ├── com.ibm.sample.zosconnect.fslogger.provider.xml\n│           └── com.ibm.sample.zosconnect.fslogger.requester.xml\n└── com.ibm.sample.zosconnect.fslogger.feature/        # Liberty Feature\n    ├── build.gradle                                    # Feature module build\n    └── OSGI-INF/\n        └── SUBSYSTEM.MF\n```\n\n## Building\n\n### Prerequisites\n\n- Java 8 or later\n- Gradle 8.5 or later\n- z/OS Connect SPI JAR\n\n### Installing the z/OS Connect SPI JAR\n\nThe z/OS Connect SPI JAR is required for compilation but is not available in public Maven repositories. You must install it manually from your z/OS Connect installation.\n\nThe SPI JAR is typically located at:\n```\n\u003czosconnect_install\u003e/dev/com.ibm.zosconnect.spi.jar\n```\nInstall it to your local Maven repository:\n```bash\nmvn install:install-file \\\n  -Dfile=/path/to/com.ibm.zosconnect.spi.jar \\\n  -DgroupId=com.ibm.zosconnect \\\n  -DartifactId=com.ibm.zosconnect.spi \\\n  -Dversion=2.0.0.0 \\\n  -Dpackaging=jar\n```\n\n**Note**: Gradle will use the local Maven repository (`~/.m2/repository`) to resolve this dependency.\n\n### Building with Gradle\n\nOnce the z/OS Connect SPI JAR is installed, build the project using Gradle:\n\n```bash\ngradle clean build\n```\n\n### Build Output\n\nAfter a successful build, you'll find:\n\n1. **OSGi Bundle JAR**\n   ```\n   com.ibm.sample.zosconnect.fslogger.interceptor/build/libs/com.ibm.sample.zosconnect.fslogger.interceptor-1.0.0.0.jar\n   ```\n\n2. **ESA File (Liberty Feature)**\n   ```\n   com.ibm.sample.zosconnect.fslogger.feature/build/distributions/fslogger-1.0.esa\n   ```\n\nThe ESA file is ready to install.\n\n## Testing\n\nA comprehensive test suite is included to ensure code quality and reliability. The test suite uses JUnit 5 and Mockito.\n\n### Running Tests\n\nRun all tests:\n```bash\ngradle test\n```\n\nRun specific test class:\n```bash\ngradle test --tests RollingFileHandlerTest\n```\n\nView test report:\n```bash\n# After running tests, open:\n# build/reports/tests/test/index.html\n```\n\n### Test Coverage\n\nThe test suite includes:\n- **RollingFileHandlerTest**: File rotation, cleanup, thread safety\n- **LogEntryProviderTest**: JSON serialization, data capture for API Provider\n- **LogEntryRequesterTest**: JSON serialization, data capture for API Requester\n- **FileSystemLoggerProviderInterceptorTest**: Provider interceptor lifecycle and behavior\n- **FileSystemLoggerRequesterInterceptorTest**: Requester interceptor lifecycle and behavior\n\nFor detailed test documentation, see [test/README.md](com.ibm.sample.zosconnect.fslogger.interceptor/test/README.md)\n\n### Tests Run Automatically\n\nTests are automatically executed during the build process:\n```bash\ngradle build\n```\n\nThe build will fail if any tests fail, ensuring code quality.\n\n## Installing the Feature\n\n1. Transfer the ESA file to a directory on your z/OS LPAR:\n\n   ```bash\n   /u/user/zosconnect/extension/fslogger-1.0.esa\n   ```\n\n2. Configure the Liberty user directory (if not already set):\n   ```bash\n   export WLP_USER_DIR=/var/zosconnect\n   ```\n\n3. Install using featureUtility:\n   ```bash\n   \u003czosconnect_install\u003e/wlp/bin/featureUtility install /u/user/zosconnect/extension/fslogger-1.0.esa\n   ```\n## Configuration\n\n### API provider Interceptor\n\nAdd the following to your `server.xml`:\n\n```xml\n\u003cfeatureManager\u003e\n    \u003cfeature\u003ezosconnect:zosConnect-3.0\u003c/feature\u003e\n    \u003cfeature\u003ezosconnect:monitoring-1.0\u003c/feature\u003e \n    \u003cfeature\u003eusr:fslogger-1.0\u003c/feature\u003e\n\u003c/featureManager\u003e\n\n\u003czosconnect_monitoring apiRequesterInterceptorsRef=\"interceptorList\"/\u003e\n\u003czosconnect_zosConnectInterceptors id=\"interceptorList\" interceptorRef=\"fileSystemProvider\"/\u003e \n\n\u003cusr_fileSystemLoggerProvider\n    id=\"fileSystemProvider\"\n    logDirectory=\"/u/user/zosconnect/logs\"\n    maxFileSize=\"10485760\"\n    maxFileCount=\"10\"\n    requestHeaders=\"Content-Type,Authorization\"\n    responseHeaders=\"Content-Type,X-Custom-Header\"\n    includeBody=\"false\"/\u003e\n```\n\n### API requester Interceptor\n\n```xml\n\u003cfeatureManager\u003e\n    \u003cfeature\u003ezosconnect:zosConnect-3.0\u003c/feature\u003e\n    \u003cfeature\u003ezosconnect:monitoring-1.0\u003c/feature\u003e \n    \u003cfeature\u003eusr:fslogger-1.0\u003c/feature\u003e\n\u003c/featureManager\u003e\n\n\u003czosconnect_monitoring apiRequesterInterceptorsRef=\"interceptorList\"/\u003e\n\u003czosconnect_zosConnectInterceptors id=\"interceptorList\" interceptorRef=\"fileSystemRequester\"/\u003e \n\n\u003cusr_fileSystemLoggerRequester\n    id=\"fileSystemRequester\"\n    logDirectory=\"/u/user/zosconnect/logs\"\n    maxFileSize=\"10485760\"\n    maxFileCount=\"10\"\n    requestHeaders=\"Content-Type,Authorization\"\n    responseHeaders=\"Content-Type,Cache-Control\"\n    includeBody=\"false\"/\u003e\n```\n\n### Configuration Parameters\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `id` | String | Yes | - | A unique identifier for this Interceptor |\n| `sequence` | Integer | No | 0 | Interceptor execution order (0-2147483647) |\n| `logDirectory` | String | Yes | - | Directory path where log files will be written |\n| `maxFileSize` | Long | No | 10485760 | Maximum size of each log file in bytes (10MB default) |\n| `maxFileCount` | Integer | No | 10 | Maximum number of log files to retain |\n| `requestHeaders` | String | No | \"\" | Comma-separated list of request header names to capture (e.g., Content-Type,Authorization). |\n| `responseHeaders` | String | No | \"\" | Comma-separated list of response header names to capture (e.g., Content-Type,X-Custom-Header). |\n| `includeBody` | Boolean | No | false | Include request and response bodies in log entries |\n\n## Log File Format\n\n### API provider Log Entry\n\n```json\n{\n  \"timestamp\": \"2026-01-14T10:15:30.123Z\",\n  \"requestId\": 123456789,\n  \"user\": \"user1\",\n  \"mappedUser\": \"USERID\",\n  \"request\": {\n    \"uri\": \"/api/v1/customers\",\n    \"method\": \"POST\",\n    \"queryString\": \"filter=active\u0026limit=10\",\n    \"headers\": {\n      \"Content-Type\": \"application/json\",\n      \"Accept\": \"application/json\"\n    },\n    \"body\": \"{\\\"customerId\\\":\\\"12345\\\"}\",\n    \"size\": 23\n  },\n  \"sor\": {\n    \"identifier\": \"CICS01\",\n    \"resource\": \"CUSTOMER\",\n    \"reference\": \"REF123\"\n  },\n  \"response\": {\n    \"statusCode\": 200,\n    \"headers\": {\n      \"Content-Type\": \"application/json\"\n    },\n    \"body\": \"{\\\"status\\\":\\\"success\\\"}\",\n    \"size\": 21\n  }\n}\n```\n\n**Note**: The `size` field is always included (when bodies exist) and represents the size in bytes (UTF-8 encoding), even when `includeBody` is set to `false`. The `body` field is only included when `includeBody` is `true`.\n\n### API Requester Log Entry\n\n```json\n{\n  \"timestamp\": \"2026-01-14T10:15:30.123Z\",\n  \"requestId\": 987654321,\n  \"user\": \"user1\",\n  \"mappedUser\": \"USERID\",\n  \"request\": {\n    \"requestType\": \"CICS\",\n    \"jobname\": \"CICSJOB\",\n    \"jobid\": \"JOB00123\",\n    \"sysname\": \"SYSA\",\n    \"cics\": {\n      \"applid\": \"CICS01\",\n      \"taskNumber\": 54321,\n      \"transid\": \"ABCD\"\n    },\n    \"headers\": {\n      \"Content-Type\": \"application/json\",\n      \"Accept\": \"application/json\"\n    },\n    \"body\": \"{\\\"query\\\":\\\"customerId\\\"}\",\n    \"size\": 24\n  },\n  \"endpoint\": {\n    \"host\": \"backend.example.com\",\n    \"port\": 8080,\n    \"method\": \"GET\",\n    \"path\": \"/customers/12345\",\n    \"queryString\": \"format=json\u0026include=details\"\n  },\n  \"response\": {\n    \"statusCode\": 200,\n    \"headers\": {\n      \"Content-Type\": \"application/json\",\n      \"Cache-Control\": \"no-cache\"\n    },\n    \"body\": \"{\\\"customer\\\":{\\\"id\\\":\\\"12345\\\"}}\",\n    \"size\": 30\n  }\n}\n```\n\n**Note**: The `requestType` field within the `request` object indicates the type of application making the request (e.g., \"CICS\", \"IMS\", \"ZOS\"). The z/OS system information (`jobname`, `jobid`, `sysname`) is included directly within the `request` object. The `cics` object is only included when `requestType` is \"CICS\", and the `ims` object is only included when `requestType` is \"IMS\".\n\n#### API Requester Log Entry with IMS\n\n```json\n{\n  \"timestamp\": \"2026-01-14T10:15:30.123Z\",\n  \"requestId\": 987654321,\n  \"user\": \"user1\",\n  \"mappedUser\": \"USERID\",\n  \"request\": {\n    \"requestType\": \"IMS\",\n    \"jobname\": \"IMSJOB\",\n    \"jobid\": \"JOB00456\",\n    \"sysname\": \"SYSB\",\n    \"ims\": {\n      \"identifier\": \"IMS01\",\n      \"regionId\": 2,\n      \"transname\": \"IMSTRAN\",\n      \"appname\": \"IMSAPP\",\n      \"psbname\": \"IMSPSB\"\n    },\n    \"headers\": {\n      \"Content-Type\": \"application/json\"\n    },\n    \"body\": \"{\\\"query\\\":\\\"customerId\\\"}\",\n    \"size\": 24\n  },\n  \"endpoint\": {\n    \"host\": \"backend.example.com\",\n    \"port\": 8080,\n    \"method\": \"GET\",\n    \"path\": \"/customers/12345\"\n  },\n  \"response\": {\n    \"statusCode\": 200,\n    \"headers\": {\n      \"Content-Type\": \"application/json\"\n    },\n    \"body\": \"{\\\"customer\\\":{\\\"id\\\":\\\"12345\\\"}}\",\n    \"size\": 30\n  }\n}\n```\n\n**Note**: The `size` field is always included (when bodies exist) in both request and response objects and represents the size in bytes (UTF-8 encoding), even when `includeBody` is set to `false`. The `body` field is only included when `includeBody` is `true`.\n\n## Log File Naming\n\nLog files are created with the interceptor ID and timestamps in the format:\n```\nzosconnect-\u003cid\u003e-YYYYMMdd-HHmmss.log\n```\n\nWhere `\u003cid\u003e` is the unique identifier specified in the interceptor configuration.\n\nExamples:\n- `zosconnect-fileSystemProvider-20260114-101530.log`\n- `zosconnect-fileSystemRequester-20260114-101530.log`\n\n**Note**: Each interceptor instance manages its own set of log files based on its ID. This allows multiple interceptor instances to write to the same directory without interfering with each other's file rotation and cleanup.\n\n## Performance Considerations\n\n- **Body Logging**: Enabling `includeBody` can significantly increase log file size and I/O overhead. Use with caution in production environments.\n- **Size Tracking**: Body sizes are always captured (even when `includeBody` is `false`) with minimal performance impact, providing valuable metrics without storing full body content.\n- **File Size**: Larger `maxFileSize` values reduce the frequency of file rotation but increase individual file sizes.\n- **File Count**: Higher `maxFileCount` values consume more disk space but provide longer retention history.\n- **Disk I/O**: The interceptor uses buffered writes and flushes after each log entry to ensure data integrity.\n\n## Security Considerations\n\n- **Sensitive Data**: Be cautious when enabling `includeBody` as it may log sensitive information such as passwords, credit card numbers, or personal data.\n- **File Permissions**: Ensure the log directory has appropriate permissions to prevent unauthorized access.\n- **Log Rotation**: Implement external log rotation or archival processes for long-term retention and compliance.\n\n## Troubleshooting\n\n### Interceptor Not Activating\n\nCheck the Liberty `messages.log` for activation messages:\n```\nFileSystemLoggerProviderInterceptor activated\nFileSystemLoggerProviderInterceptor initialized with logDirectory=...\n```\n\n### Log Files Not Created\n\n1. Verify the `logDirectory` exists and is writable\n2. Check Liberty has permissions to create files in the directory\n3. Review `messages.log` for error messages\n\n### Log Files Not Rotating\n\n1. Verify `maxFileSize` is set appropriately\n2. Check disk space availability\n3. Ensure `maxFileCount` is greater than 1\n\n## License\n\nCopyright IBM Corporation 2026\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\n## Support\n\nThis is sample code and is not officially supported by IBM. Use at your own risk.\n\nPlease raise an issue in this repository if you encounter a problem using the sample code.\n\n## Version History\n\n- **1.0.0** (2026-01-15)\n  - Initial release\n  - API provider interceptor\n  - API requester interceptor\n  - Rolling file handler\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzosconnect%2Fsample-fslogger-interceptor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzosconnect%2Fsample-fslogger-interceptor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzosconnect%2Fsample-fslogger-interceptor/lists"}