{"id":19765811,"url":"https://github.com/watertreestar/tidy-log","last_synced_at":"2025-08-11T06:42:11.331Z","repository":{"id":217822923,"uuid":"203745551","full_name":"watertreestar/tidy-log","owner":"watertreestar","description":"light weight logger for Java","archived":false,"fork":false,"pushed_at":"2020-10-13T15:31:30.000Z","size":12,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-28T10:40:14.427Z","etag":null,"topics":["java","logger","logging","slf4j-api"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/watertreestar.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2019-08-22T08:07:51.000Z","updated_at":"2021-11-24T02:14:16.000Z","dependencies_parsed_at":"2024-01-18T12:07:34.372Z","dependency_job_id":"acb4910d-a2da-4eb1-a30f-1e64b11ada37","html_url":"https://github.com/watertreestar/tidy-log","commit_stats":null,"previous_names":["watertreestar/tidy-log"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/watertreestar/tidy-log","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/watertreestar%2Ftidy-log","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/watertreestar%2Ftidy-log/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/watertreestar%2Ftidy-log/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/watertreestar%2Ftidy-log/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/watertreestar","download_url":"https://codeload.github.com/watertreestar/tidy-log/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/watertreestar%2Ftidy-log/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":269843095,"owners_count":24484111,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-11T02:00:10.019Z","response_time":75,"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","logger","logging","slf4j-api"],"created_at":"2024-11-12T04:19:31.636Z","updated_at":"2025-08-11T06:42:11.280Z","avatar_url":"https://github.com/watertreestar.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# klog\n\na simple implementation of slf4j api\n\nslf4j可以选择不同的日志实现，SLF4J隐藏了具体的转换、适配细节，将应用和具体日志框架解耦开来，如果在类路径中没有发现绑定的日志实现，SLF4J默认使用NOP实现。\n\n所以，slf4j只是一套标准的日志API，需要自己去实现，在选择某一个具体的日志实现框架时，只需要将这个框架添加到classpath中，slf4j可以自动实现绑定，这到底是如何实现的呢\n\n\n## 自动绑定实现类的原理\n可以先看看slf4j获取Logger的源码，跟着源码找到其实现自动绑定的原理\n\n从LoggerFactory#getLogger(String name)出发：\n\n```java\n    public static Logger getLogger(String name) {\n        ILoggerFactory iLoggerFactory = getILoggerFactory();\n        return iLoggerFactory.getLogger(name);\n    }\n    // .....\n    public static ILoggerFactory getILoggerFactory() {\n        if (INITIALIZATION_STATE == UNINITIALIZED) {\n            synchronized (LoggerFactory.class) {\n                if (INITIALIZATION_STATE == UNINITIALIZED) {\n                    INITIALIZATION_STATE = ONGOING_INITIALIZATION;\n                    // 初始化\n                    performInitialization();\n                }\n            }\n        }\n        switch (INITIALIZATION_STATE) {\n        case SUCCESSFUL_INITIALIZATION:\n            // 调用StaticLoggerBinder获取LoggerFacetoy\n            return StaticLoggerBinder.getSingleton().getLoggerFactory();\n        case NOP_FALLBACK_INITIALIZATION:\n            return NOP_FALLBACK_FACTORY;\n        case FAILED_INITIALIZATION:\n            throw new IllegalStateException(UNSUCCESSFUL_INIT_MSG);\n        case ONGOING_INITIALIZATION:\n            // support re-entrant behavior.\n            // See also http://jira.qos.ch/browse/SLF4J-97\n            return SUBST_FACTORY;\n        }\n        throw new IllegalStateException(\"Unreachable code\");\n    }\n    \n    // performInitialization() 方法\n    private final static void performInitialization() {\n        bind();\n        if (INITIALIZATION_STATE == SUCCESSFUL_INITIALIZATION) {\n            versionSanityCheck();\n        }\n    }\n    \n    // bind()方法，关键点\n    private final static void bind() {\n        try {\n            Set\u003cURL\u003e staticLoggerBinderPathSet = null;\n            // skip check under android, see also\n            // http://jira.qos.ch/browse/SLF4J-328\n            if (!isAndroid()) {\n                staticLoggerBinderPathSet = findPossibleStaticLoggerBinderPathSet();\n                reportMultipleBindingAmbiguity(staticLoggerBinderPathSet);\n            }\n            // the next line does the binding\n            // 绑定开始\n            StaticLoggerBinder.getSingleton();\n            // 修改初始化状态\n            INITIALIZATION_STATE = SUCCESSFUL_INITIALIZATION;\n            reportActualBinding(staticLoggerBinderPathSet);\n            fixSubstituteLoggers();\n            replayEvents();\n            // release all resources in SUBST_FACTORY\n            SUBST_FACTORY.clear();\n        } catch (NoClassDefFoundError ncde) {\n            String msg = ncde.getMessage();\n            if (messageContainsOrgSlf4jImplStaticLoggerBinder(msg)) {\n                // 从这里可以看出需要有一个org.slf.impl.StaticLoggerBinder类\n                INITIALIZATION_STATE = NOP_FALLBACK_INITIALIZATION;\n                Util.report(\"Failed to load class \\\"org.slf4j.impl.StaticLoggerBinder\\\".\");\n                Util.report(\"Defaulting to no-operation (NOP) logger implementation\");\n                Util.report(\"See \" + NO_STATICLOGGERBINDER_URL + \" for further details.\");\n            } else {\n                failedBinding(ncde);\n                throw ncde;\n            }\n        } catch (java.lang.NoSuchMethodError nsme) {\n            String msg = nsme.getMessage();\n            // 从这里我们可以看出需要包含一个getSingleton()方法\n            if (msg != null \u0026\u0026 msg.contains(\"org.slf4j.impl.StaticLoggerBinder.getSingleton()\")) {\n                INITIALIZATION_STATE = FAILED_INITIALIZATION;\n                Util.report(\"slf4j-api 1.6.x (or later) is incompatible with this binding.\");\n                Util.report(\"Your binding is version 1.5.5 or earlier.\");\n                Util.report(\"Upgrade your binding to version 1.6.x.\");\n            }\n            throw nsme;\n        } catch (Exception e) {\n            failedBinding(e);\n            throw new IllegalStateException(\"Unexpected initialization failure\", e);\n        }\n    }\n    \n    \n```\n\n## 一个简单的实现\n\n\n\n\u003e 参考自slf4j-simple的实现","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwatertreestar%2Ftidy-log","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwatertreestar%2Ftidy-log","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwatertreestar%2Ftidy-log/lists"}