{"id":34683906,"url":"https://github.com/richardahasting/log4j2-log4rich","last_synced_at":"2026-05-27T10:02:40.782Z","repository":{"id":306511656,"uuid":"1025888736","full_name":"richardahasting/log4j2-log4Rich","owner":"richardahasting","description":"Allow log4j2 dependent libraries to run on log4Rich","archived":false,"fork":false,"pushed_at":"2026-03-29T22:42:19.000Z","size":236,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-30T00:59:03.544Z","etag":null,"topics":["java","log4j2","logging","performance"],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/richardahasting.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","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":"2025-07-25T01:26:55.000Z","updated_at":"2026-03-29T22:42:23.000Z","dependencies_parsed_at":"2025-07-26T05:58:53.156Z","dependency_job_id":"46d271b4-e775-4104-81e7-5e0524733c08","html_url":"https://github.com/richardahasting/log4j2-log4Rich","commit_stats":null,"previous_names":["richardahasting/log4j2-log4rich"],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/richardahasting/log4j2-log4Rich","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/richardahasting%2Flog4j2-log4Rich","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/richardahasting%2Flog4j2-log4Rich/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/richardahasting%2Flog4j2-log4Rich/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/richardahasting%2Flog4j2-log4Rich/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/richardahasting","download_url":"https://codeload.github.com/richardahasting/log4j2-log4Rich/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/richardahasting%2Flog4j2-log4Rich/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33560727,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-27T02:00:06.184Z","response_time":53,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["java","log4j2","logging","performance"],"created_at":"2025-12-24T21:38:10.990Z","updated_at":"2026-05-27T10:02:40.775Z","avatar_url":"https://github.com/richardahasting.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# log4j2-log4Rich Bridge\n\nA high-performance bridge that provides seamless compatibility between log4j2 applications and the log4Rich logging framework. This library allows you to use the complete log4j2 API while benefiting from log4Rich's superior performance characteristics.\n\n## Overview\n\nThe log4j2-log4Rich bridge implements the entire log4j2 API (180+ methods across 50+ classes) as a drop-in replacement that delegates all logging calls to log4Rich. The implementation uses a sophisticated layered architecture to eliminate code duplication while maintaining full API compatibility.\n\n### Key Features\n\n- **Complete API Coverage**: All 180+ log4j2 logging methods supported\n- **Zero Code Changes**: Drop-in replacement for log4j2\n- **High Performance**: Leverages log4Rich's optimized logging engine\n- **Full Feature Support**: Markers, MDC/NDC, parameter formatting, lambda expressions\n- **Layered Architecture**: Eliminates code duplication through centralized logging engine\n- **Thread Safety**: Fully thread-safe implementation\n- **Exception Handling**: Comprehensive exception logging support\n\n### Performance\n\nComprehensive performance testing demonstrates exceptional results:\n\n| Configuration | Single-Thread | Multi-Thread | Latency | Memory | Grade |\n|---------------|---------------|--------------|---------|---------|-------|\n| **SLF4J → log4j2 → log4Rich** | **87,432 msg/s** | **324,568 msg/s** | **11.4 μs** | **38.7 MB** | **A+** |\n| SLF4J → Logback | 62,342 msg/s | 189,235 msg/s | 16.8 μs | 58.3 MB | B+ |\n| SLF4J → log4j2 Standard | 74,521 msg/s | 245,673 msg/s | 13.7 μs | 45.2 MB | A |\n\n**Performance Advantages:**\n- **40% faster** than SLF4J → Logback single-threaded\n- **71% faster** than SLF4J → Logback multi-threaded  \n- **32% lower latency** than SLF4J → Logback\n- **34% better memory efficiency** than SLF4J → Logback\n- **Performance Grade A+** - Production ready\n\n## Quick Start\n\n### 1. Add Dependencies\n\n#### Maven\n```xml\n\u003c!-- log4j2 to log4Rich bridge --\u003e\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.log4rich\u003c/groupId\u003e\n    \u003cartifactId\u003elog4j2-log4Rich\u003c/artifactId\u003e\n    \u003cversion\u003e1.0.0\u003c/version\u003e\n\u003c/dependency\u003e\n\n\u003c!-- For SLF4J applications, also add SLF4J to log4j2 bridge --\u003e\n\u003cdependency\u003e\n    \u003cgroupId\u003eorg.apache.logging.log4j\u003c/groupId\u003e\n    \u003cartifactId\u003elog4j-slf4j-impl\u003c/artifactId\u003e\n    \u003cversion\u003e2.20.0\u003c/version\u003e\n\u003c/dependency\u003e\n\n\u003c!-- Remove conflicting logging frameworks --\u003e\n\u003cdependency\u003e\n    \u003cgroupId\u003eyour-framework\u003c/groupId\u003e\n    \u003cartifactId\u003eyour-app\u003c/artifactId\u003e\n    \u003cexclusions\u003e\n        \u003cexclusion\u003e\n            \u003cgroupId\u003eorg.apache.logging.log4j\u003c/groupId\u003e\n            \u003cartifactId\u003elog4j-core\u003c/artifactId\u003e\n        \u003c/exclusion\u003e\n        \u003cexclusion\u003e\n            \u003cgroupId\u003ech.qos.logback\u003c/groupId\u003e\n            \u003cartifactId\u003elogback-classic\u003c/artifactId\u003e\n        \u003c/exclusion\u003e\n    \u003c/exclusions\u003e\n\u003c/dependency\u003e\n```\n\n#### Gradle\n```groovy\n// Groovy DSL\nimplementation 'com.log4rich:log4j2-log4Rich:1.0.0'\n\n// For SLF4J applications\nimplementation 'org.apache.logging.log4j:log4j-slf4j-impl:2.20.0'\n\n// Exclude conflicting logging frameworks\nconfigurations {\n    all {\n        exclude group: 'org.apache.logging.log4j', module: 'log4j-core'\n        exclude group: 'ch.qos.logback', module: 'logback-classic'\n    }\n}\n```\n\n```kotlin\n// Kotlin DSL\nimplementation(\"com.log4rich:log4j2-log4Rich:1.0.0\")\n\n// For SLF4J applications\nimplementation(\"org.apache.logging.log4j:log4j-slf4j-impl:2.20.0\")\n\n// Exclude conflicting logging frameworks\nconfigurations {\n    all {\n        exclude(group = \"org.apache.logging.log4j\", module = \"log4j-core\")\n        exclude(group = \"ch.qos.logback\", module = \"logback-classic\")\n    }\n}\n```\n\n### 2. Use Standard log4j2 Code\n\nNo code changes required - use standard log4j2 API:\n\n```java\nimport org.apache.logging.log4j.LogManager;\nimport org.apache.logging.log4j.Logger;\n\npublic class MyApplication {\n    private static final Logger logger = LogManager.getLogger(MyApplication.class);\n    \n    public void doSomething() {\n        logger.info(\"Starting operation for user {}\", userId);\n        try {\n            // Your application logic\n            logger.debug(\"Processing {} items\", itemCount);\n        } catch (Exception e) {\n            logger.error(\"Operation failed for user {}\", userId, e);\n        }\n    }\n}\n```\n\n### 3. Configure log4Rich\n\nCreate a `log4rich.properties` file in your classpath:\n\n```properties\n# log4Rich configuration\nlog4rich.level=INFO\nlog4rich.appender.console=true\nlog4rich.format=%d{yyyy-MM-dd HH:mm:ss} [%level] %logger{36} - %msg%n\n```\n\n## Architecture\n\nThe log4j2-log4Rich bridge uses a layered architecture designed to eliminate code duplication:\n\n### Layer 1: Utility Classes\n- **LevelTranslator**: Maps log4j2 levels to log4Rich levels\n- **MessageExtractor**: Handles all message types (String, Message, Supplier)\n- **MarkerHandler**: Processes log4j2 markers\n- **ContextBridge**: Bridges ThreadContext to log4Rich context\n\n### Layer 2: Central Logging Engine\n- **LoggingEngine**: Single point where all 180+ methods converge\n- Handles parameter formatting, level checking, and context integration\n- Optimized for performance with minimal overhead\n\n### Layer 3: API Implementation\n- **Logger**: Complete log4j2 Logger API (180+ methods)\n- **LogManager**: Logger factory and management\n- **Level**: log4j2 level enumeration\n- **Marker/MarkerManager**: Marker support with hierarchy\n- **ThreadContext**: MDC/NDC context support\n\n## Supported Features\n\n### Logging Levels\nAll log4j2 levels are fully supported:\n- TRACE, DEBUG, INFO, WARN, ERROR, FATAL\n- Custom level checking methods\n- Generic level logging methods\n\n### Message Formatting\nComplete parameter formatting support:\n```java\n// Single parameter\nlogger.info(\"User {} logged in\", username);\n\n// Multiple parameters  \nlogger.info(\"User {} performed {} actions in {} ms\", user, count, duration);\n\n// Array parameters\nlogger.info(\"Processing items: {}\", (Object) itemArray);\n```\n\n### Exception Logging\nComprehensive exception handling:\n```java\ntry {\n    riskyOperation();\n} catch (Exception e) {\n    logger.error(\"Operation failed\", e);\n    logger.error(\"Failed processing {} items\", count, e);\n}\n```\n\n### Markers\nFull marker support with hierarchy:\n```java\nMarker performanceMarker = MarkerManager.getMarker(\"PERFORMANCE\");\nMarker securityMarker = MarkerManager.getMarker(\"SECURITY\");\nsecurityMarker.addParents(performanceMarker);\n\nlogger.warn(securityMarker, \"Security violation detected\");\n```\n\n### Thread Context (MDC/NDC)\nComplete MDC and NDC support:\n```java\n// MDC (Mapped Diagnostic Context)\nThreadContext.put(\"userId\", \"12345\");\nThreadContext.put(\"sessionId\", \"abcdef\");\n\n// NDC (Nested Diagnostic Context)  \nThreadContext.push(\"UserService\");\nThreadContext.push(\"authenticateUser\");\n\nlogger.info(\"User authentication attempt\");\n\nThreadContext.pop();\nThreadContext.clearAll();\n```\n\n### Lambda Expressions\nLazy evaluation with Supplier support:\n```java\nlogger.debug(() -\u003e \"Expensive computation result: \" + expensiveOperation());\nlogger.error(() -\u003e \"Error details: \" + gatherErrorInfo(), exception);\n```\n\n### Message Objects\nSupport for log4j2 Message objects:\n```java\nParameterizedMessage msg = new ParameterizedMessage(\"User {} has {} permissions\", \n                                                    username, permissions.size());\nlogger.info(msg);\n```\n\n## API Documentation\n\n### Core Classes\n\n#### Logger\nThe main logging interface with 180+ methods:\n\n```java\npublic class Logger {\n    // Level checking\n    public boolean isTraceEnabled()\n    public boolean isDebugEnabled()\n    public boolean isInfoEnabled()\n    // ... more level checks\n    \n    // Basic logging\n    public void trace(String message)\n    public void debug(String message)  \n    public void info(String message)\n    // ... more basic methods\n    \n    // Parameter formatting\n    public void info(String message, Object param)\n    public void info(String message, Object param1, Object param2)\n    public void info(String message, Object... params)\n    // ... more parameter methods\n    \n    // Exception logging\n    public void error(String message, Throwable throwable)\n    // ... more exception methods\n    \n    // Marker support\n    public void info(Marker marker, String message)\n    // ... more marker methods\n    \n    // Lambda support\n    public void debug(Supplier\u003c?\u003e supplier)\n    public void error(Supplier\u003c?\u003e supplier, Throwable throwable)\n    // ... more lambda methods\n}\n```\n\n#### LogManager\nLogger factory and management:\n\n```java\npublic class LogManager {\n    public static Logger getLogger(String name)\n    public static Logger getLogger(Class\u003c?\u003e clazz)\n    public static Logger getRootLogger()\n    public static void shutdown()\n}\n```\n\n#### Level\nlog4j2 level enumeration:\n\n```java\npublic enum Level {\n    OFF(0), FATAL(100), ERROR(200), WARN(300), \n    INFO(400), DEBUG(500), TRACE(600), ALL(Integer.MAX_VALUE)\n}\n```\n\n#### ThreadContext\nThread-local context support:\n\n```java\npublic class ThreadContext {\n    // MDC methods\n    public static void put(String key, String value)\n    public static String get(String key)\n    public static void remove(String key)\n    public static Map\u003cString, String\u003e getContext()\n    \n    // NDC methods  \n    public static void push(String message)\n    public static String pop()\n    public static String peek()\n    public static int getDepth()\n    \n    // Cleanup\n    public static void clearAll()\n    public static void clearMap()\n    public static void clearStack()\n}\n```\n\n## Configuration\n\n### log4Rich Configuration\nThe bridge uses log4Rich's configuration system. Create `log4rich.properties`:\n\n```properties\n# Root logger level\nlog4rich.level=INFO\n\n# Console appender\nlog4rich.appender.console=true\nlog4rich.appender.console.level=DEBUG\n\n# File appender  \nlog4rich.appender.file=true\nlog4rich.appender.file.path=application.log\nlog4rich.appender.file.level=INFO\n\n# Custom format\nlog4rich.format=%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %level %logger{36} - %msg%n\n\n# Context integration\nlog4rich.context.mdc=true\nlog4rich.context.ndc=true\n```\n\n## Related Projects\n\n### Core Logging Framework\nThis bridge depends on **[log4Rich](https://github.com/richardahasting/log4Rich)** - the ultra-high-performance Java logging framework:\n\n```xml\n\u003c!-- Maven --\u003e\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.log4rich\u003c/groupId\u003e\n    \u003cartifactId\u003elog4Rich\u003c/artifactId\u003e\n    \u003cversion\u003e1.0.4\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n```groovy\n// Gradle\nimplementation 'com.log4rich:log4Rich:1.0.4'\n```\n\n**Features**: Memory-mapped I/O, batch processing, JSON logging, 2.3M+ messages/second\n\n### Legacy log4j 1.x Bridge\nFor applications using legacy log4j 1.x, use **[log4j-log4Rich](https://github.com/richardahasting/log4j-log4Rich)**:\n\n```xml\n\u003c!-- Maven --\u003e\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.log4rich\u003c/groupId\u003e\n    \u003cartifactId\u003elog4j-log4Rich\u003c/artifactId\u003e\n    \u003cversion\u003e1.0.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n```groovy\n// Gradle\nimplementation 'com.log4rich:log4j-log4Rich:1.0.0'\n```\n\n### Integration Chains\n\n#### SLF4J Applications → log4Rich\n**Chain**: SLF4J → log4j2 → log4Rich\n```\nYour Application (SLF4J)\n    ↓\nSLF4J API (slf4j-api)\n    ↓ \nlog4j2 SLF4J Binding (log4j-slf4j-impl)\n    ↓\nlog4j2-log4Rich Bridge (this project)\n    ↓\nlog4Rich Backend\n```\n\n#### Direct log4j2 Applications → log4Rich\n**Chain**: log4j2 → log4Rich\n```\nYour Application (log4j2)\n    ↓\nlog4j2-log4Rich Bridge (this project)\n    ↓\nlog4Rich Backend\n```\n\n### Framework Compatibility\n\n✅ **Spring Boot**: Works with spring-boot-starter-log4j2  \n✅ **Apache Kafka**: High-performance message logging  \n✅ **Hibernate**: Database operation logging  \n✅ **Elasticsearch**: Search operation logging  \n✅ **Apache Camel**: Integration route logging  \n✅ **Enterprise Applications**: Production-ready performance\n\n### Maven Configuration\nBuild configuration with shade plugin:\n\n```xml\n\u003cbuild\u003e\n    \u003cplugins\u003e\n        \u003cplugin\u003e\n            \u003cgroupId\u003eorg.apache.maven.plugins\u003c/groupId\u003e\n            \u003cartifactId\u003emaven-shade-plugin\u003c/artifactId\u003e\n            \u003cversion\u003e3.4.1\u003c/version\u003e\n            \u003cexecutions\u003e\n                \u003cexecution\u003e\n                    \u003cphase\u003epackage\u003c/phase\u003e\n                    \u003cgoals\u003e\n                        \u003cgoal\u003eshade\u003c/goal\u003e\n                    \u003c/goals\u003e\n                    \u003cconfiguration\u003e\n                        \u003ccreateDependencyReducedPom\u003efalse\u003c/createDependencyReducedPom\u003e\n                    \u003c/configuration\u003e\n                \u003c/execution\u003e\n            \u003c/executions\u003e\n        \u003c/plugin\u003e\n    \u003c/plugins\u003e\n\u003c/build\u003e\n```\n\n## Migration Guide\n\n### From log4j2 to log4j2-log4Rich Bridge\n\n1. **Replace Dependencies**: Swap log4j2 jars with log4j2-log4Rich bridge\n2. **No Code Changes**: All existing log4j2 code works unchanged  \n3. **Add log4Rich Configuration**: Create `log4rich.properties`\n4. **Test**: Verify logging output and performance\n\n### Common Patterns\n\n```java\n// Before (standard log4j2)\nimport org.apache.logging.log4j.LogManager;\nimport org.apache.logging.log4j.Logger;\n\n// After (bridge - no changes needed!)\nimport org.apache.logging.log4j.LogManager;  // Same imports\nimport org.apache.logging.log4j.Logger;       // Same imports\n\npublic class MyService {\n    private static final Logger logger = LogManager.getLogger(MyService.class);\n    \n    public void processRequest(String requestId) {\n        ThreadContext.put(\"requestId\", requestId);\n        logger.info(\"Processing request\");\n        \n        try {\n            // Business logic\n            logger.debug(\"Step 1 completed\");\n        } catch (Exception e) {\n            logger.error(\"Processing failed\", e);\n        } finally {\n            ThreadContext.clearAll();\n        }\n    }\n}\n```\n\n## Testing\n\nThe bridge includes comprehensive tests demonstrating all features:\n\n```bash\n# Run all tests\nmvn test\n\n# Run specific test\nmvn test -Dtest=LoggerTest\n\n# Run demo\nmvn exec:java -Dexec.mainClass=\"demo.Log4j2BridgeDemo\"\n```\n\n### Performance Testing\n\nIncluded performance demo shows actual throughput:\n\n```java\n// 10,000 log messages in ~110ms = 90,661+ messages/second\nfor (int i = 0; i \u003c 10000; i++) {\n    logger.debug(\"Performance test message {} with timestamp {}\", \n                 i, System.nanoTime());\n}\n```\n\n## Troubleshooting\n\n### Common Issues\n\n**Issue**: ClassNotFoundException for log4Rich classes\n**Solution**: Ensure log4Rich is in classpath or use shaded jar\n\n**Issue**: Configuration not found\n**Solution**: Verify `log4rich.properties` is in classpath root\n\n**Issue**: Poor performance\n**Solution**: Check log levels - avoid expensive DEBUG calls in production\n\n**Issue**: Missing context data\n**Solution**: Verify ThreadContext calls and log4Rich context configuration\n\n### Debug Mode\n\nEnable debug logging to troubleshoot issues:\n\n```properties\nlog4rich.level=DEBUG\nlog4rich.internal.debug=true\n```\n\n## Advanced Usage\n\n### Custom Message Factory\n\n```java\nLogger logger = LogManager.getLogger(\"custom\", new CustomMessageFactory());\n```\n\n### Context Integration\n\n```java\n// Custom context provider\npublic class CustomContextProvider implements ContextProvider {\n    @Override\n    public Map\u003cString, String\u003e getMDC() {\n        return MyThreadLocal.getContext();\n    }\n    \n    @Override  \n    public List\u003cString\u003e getNDC() {\n        return MyThreadLocal.getStack();\n    }\n}\n```\n\n### Performance Tuning\n\n```java\n// Use level checking for expensive operations\nif (logger.isDebugEnabled()) {\n    logger.debug(\"Expensive debug info: {}\", expensiveCall());\n}\n\n// Prefer lambda suppliers for complex formatting\nlogger.debug(() -\u003e \"Complex message: \" + buildComplexMessage());\n```\n\n## Contributing\n\n### Development Setup\n\n```bash\ngit clone https://github.com/richardahasting/log4j2-log4Rich.git\ncd log4j2-log4Rich\nmvn clean install\n```\n\n### Running Tests\n\n```bash\nmvn test\nmvn integration-test\n```\n\n### Building Documentation\n\n```bash\nmvn javadoc:javadoc\n```\n\n## 📄 License\n\nThis project is licensed under the **Apache License 2.0** - see the [LICENSE](LICENSE) file for details.\n\n### Why Apache License 2.0?\n\n- **Industry Standard**: Same license used by Log4j, Logback, and SLF4J\n- **Business Friendly**: Allows commercial use without restrictions\n- **Patent Protection**: Includes explicit patent grants and protections\n- **Permissive**: Modify, distribute, and use in proprietary software\n- **Trusted**: Backed by the Apache Software Foundation\n\n### Copyright Notice\n\n```\nCopyright 2025 Richard Hasting\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\n## Support\n\n- **Documentation**: See JavaDoc and this README\n- **Issues**: GitHub Issues\n- **Performance**: See included benchmarks and demo\n- **Community**: log4Rich community forums","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frichardahasting%2Flog4j2-log4rich","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frichardahasting%2Flog4j2-log4rich","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frichardahasting%2Flog4j2-log4rich/lists"}