You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by dw...@apache.org on 2021/12/16 10:18:40 UTC
[lucene] branch main updated: LUCENE-10313: drop log4j from luke (#544)
This is an automated email from the ASF dual-hosted git repository.
dweiss pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/lucene.git
The following commit(s) were added to refs/heads/main by this push:
new 36638dc LUCENE-10313: drop log4j from luke (#544)
36638dc is described below
commit 36638dcb1e2510d3272c1d2526cf8c0a9dde18e3
Author: Dawid Weiss <da...@carrotsearch.com>
AuthorDate: Thu Dec 16 11:18:34 2021 +0100
LUCENE-10313: drop log4j from luke (#544)
---
lucene/CHANGES.txt | 4 +
.../distribution/src/binary-release/bin/luke.cmd | 2 +-
lucene/distribution/src/binary-release/bin/luke.sh | 2 +-
lucene/licenses/log4j-api-2.15.0.jar.sha1 | 1 -
lucene/licenses/log4j-api-LICENSE-ASL.txt | 201 ---------------------
lucene/licenses/log4j-api-NOTICE.txt | 17 --
lucene/licenses/log4j-core-2.15.0.jar.sha1 | 1 -
lucene/licenses/log4j-core-LICENSE-ASL.txt | 201 ---------------------
lucene/licenses/log4j-core-NOTICE.txt | 17 --
lucene/luke/build.gradle | 2 -
lucene/luke/src/distribution/README.md | 2 +-
.../apache/lucene/luke/app/AbstractHandler.java | 7 +-
.../org/apache/lucene/luke/app/IndexHandler.java | 9 +-
.../apache/lucene/luke/app/desktop/LukeMain.java | 15 +-
.../app/desktop/components/LogsPanelProvider.java | 131 ++++++++++++--
.../app/desktop/components/LukeWindowProvider.java | 25 +--
.../app/desktop/components/TabbedPaneProvider.java | 9 +-
.../dialog/documents/AddDocumentDialogFactory.java | 9 +-
.../dialog/menubar/CheckIndexDialogFactory.java | 5 +-
.../dialog/menubar/CreateIndexDialogFactory.java | 5 +-
.../dialog/menubar/ExportTermsDialogFactory.java | 7 +-
.../dialog/menubar/OpenIndexDialogFactory.java | 5 +-
.../luke/app/desktop/util/ExceptionHandler.java | 7 +-
.../luke/app/desktop/util/TextAreaAppender.java | 108 -----------
.../lucene/luke/models/commits/CommitsImpl.java | 6 +-
.../luke/models/documents/DocumentsImpl.java | 44 ++---
.../luke/models/documents/TermVectorsAdapter.java | 8 +-
.../lucene/luke/models/search/SearchImpl.java | 10 +-
.../apache/lucene/luke/models/util/IndexUtils.java | 33 ++--
.../util/twentynewsgroups/MessageFilesParser.java | 9 +-
.../lucene/luke/util/CircularLogBufferHandler.java | 114 ++++++++++++
.../org/apache/lucene/luke/util/LoggerFactory.java | 56 ++----
.../luke/app/desktop/messages/messages.properties | 2 +-
versions.lock | 2 -
versions.props | 1 -
35 files changed, 349 insertions(+), 728 deletions(-)
diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index c1ce6ca..9b98105 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -68,6 +68,10 @@ New Features
Improvements
---------------------
+* LUCENE-10313: use java util logging in Luke. Add dynamic log filtering. Drop
+ the persistent log previously written to ~/.luke.d/luke.log. Configure Java's default
+ logging handlers to persist Luke logs according to your needs. (Tomoko Uchida, Dawid Weiss)
+
* LUCENE-10238: Upgrade icu4j dependency to 70.1. (Dawid Weiss)
* LUCENE-9820: Extract BKD tree interface and move intersecting logic to the
diff --git a/lucene/distribution/src/binary-release/bin/luke.cmd b/lucene/distribution/src/binary-release/bin/luke.cmd
index d5a3ce1..b4591ae 100644
--- a/lucene/distribution/src/binary-release/bin/luke.cmd
+++ b/lucene/distribution/src/binary-release/bin/luke.cmd
@@ -17,5 +17,5 @@
SETLOCAL
SET MODULES=%~dp0..
-start javaw --module-path "%MODULES%\modules;%MODULES%\modules-thirdparty" --add-modules jdk.unsupported,org.apache.logging.log4j --module org.apache.lucene.luke
+start javaw --module-path "%MODULES%\modules;%MODULES%\modules-thirdparty" --add-modules jdk.unsupported --module org.apache.lucene.luke
ENDLOCAL
diff --git a/lucene/distribution/src/binary-release/bin/luke.sh b/lucene/distribution/src/binary-release/bin/luke.sh
index 0914532..053edda 100644
--- a/lucene/distribution/src/binary-release/bin/luke.sh
+++ b/lucene/distribution/src/binary-release/bin/luke.sh
@@ -17,4 +17,4 @@
MODULES=`dirname "$0"`/..
MODULES=`cd "$MODULES" && pwd`
-java --module-path "$MODULES/modules:$MODULES/modules-thirdparty" --add-modules jdk.unsupported,org.apache.logging.log4j --module org.apache.lucene.luke
+java --module-path "$MODULES/modules:$MODULES/modules-thirdparty" --add-modules jdk.unsupported --module org.apache.lucene.luke
diff --git a/lucene/licenses/log4j-api-2.15.0.jar.sha1 b/lucene/licenses/log4j-api-2.15.0.jar.sha1
deleted file mode 100644
index a699db8..0000000
--- a/lucene/licenses/log4j-api-2.15.0.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-4a5aa7e55a29391c6f66e0b259d5189aa11e45d0
\ No newline at end of file
diff --git a/lucene/licenses/log4j-api-LICENSE-ASL.txt b/lucene/licenses/log4j-api-LICENSE-ASL.txt
deleted file mode 100644
index f49a4e1..0000000
--- a/lucene/licenses/log4j-api-LICENSE-ASL.txt
+++ /dev/null
@@ -1,201 +0,0 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
\ No newline at end of file
diff --git a/lucene/licenses/log4j-api-NOTICE.txt b/lucene/licenses/log4j-api-NOTICE.txt
deleted file mode 100644
index ebba5ac..0000000
--- a/lucene/licenses/log4j-api-NOTICE.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-Apache Log4j
-Copyright 1999-2017 Apache Software Foundation
-
-This product includes software developed at
-The Apache Software Foundation (http://www.apache.org/).
-
-ResolverUtil.java
-Copyright 2005-2006 Tim Fennell
-
-Dumbster SMTP test server
-Copyright 2004 Jason Paul Kitchen
-
-TypeUtil.java
-Copyright 2002-2012 Ramnivas Laddad, Juergen Hoeller, Chris Beams
-
-picocli (http://picocli.info)
-Copyright 2017 Remko Popma
\ No newline at end of file
diff --git a/lucene/licenses/log4j-core-2.15.0.jar.sha1 b/lucene/licenses/log4j-core-2.15.0.jar.sha1
deleted file mode 100644
index b0ab8d9..0000000
--- a/lucene/licenses/log4j-core-2.15.0.jar.sha1
+++ /dev/null
@@ -1 +0,0 @@
-ba55c13d7ac2fd44df9cc8074455719a33f375b9
\ No newline at end of file
diff --git a/lucene/licenses/log4j-core-LICENSE-ASL.txt b/lucene/licenses/log4j-core-LICENSE-ASL.txt
deleted file mode 100644
index f49a4e1..0000000
--- a/lucene/licenses/log4j-core-LICENSE-ASL.txt
+++ /dev/null
@@ -1,201 +0,0 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
\ No newline at end of file
diff --git a/lucene/licenses/log4j-core-NOTICE.txt b/lucene/licenses/log4j-core-NOTICE.txt
deleted file mode 100644
index ebba5ac..0000000
--- a/lucene/licenses/log4j-core-NOTICE.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-Apache Log4j
-Copyright 1999-2017 Apache Software Foundation
-
-This product includes software developed at
-The Apache Software Foundation (http://www.apache.org/).
-
-ResolverUtil.java
-Copyright 2005-2006 Tim Fennell
-
-Dumbster SMTP test server
-Copyright 2004 Jason Paul Kitchen
-
-TypeUtil.java
-Copyright 2002-2012 Ramnivas Laddad, Juergen Hoeller, Chris Beams
-
-picocli (http://picocli.info)
-Copyright 2017 Remko Popma
\ No newline at end of file
diff --git a/lucene/luke/build.gradle b/lucene/luke/build.gradle
index 23c843a..fe556ca 100644
--- a/lucene/luke/build.gradle
+++ b/lucene/luke/build.gradle
@@ -27,8 +27,6 @@ ext {
dependencies {
api project(':lucene:core')
- implementation 'org.apache.logging.log4j:log4j-core'
-
implementation project(':lucene:codecs')
implementation project(':lucene:backward-codecs')
implementation project(':lucene:analysis:common')
diff --git a/lucene/luke/src/distribution/README.md b/lucene/luke/src/distribution/README.md
index 0548fd1..4ff8bc7 100644
--- a/lucene/luke/src/distribution/README.md
+++ b/lucene/luke/src/distribution/README.md
@@ -27,7 +27,7 @@ java -jar ${luke.cmd}
or, using Java modules:
```
-java --module-path . --add-modules jdk.unsupported,org.apache.logging.log4j --module org.apache.lucene.luke
+java --module-path . --add-modules jdk.unsupported --module org.apache.lucene.luke
```
Happy index hacking!
diff --git a/lucene/luke/src/java/org/apache/lucene/luke/app/AbstractHandler.java b/lucene/luke/src/java/org/apache/lucene/luke/app/AbstractHandler.java
index 5abd9d9..ad77385a 100644
--- a/lucene/luke/src/java/org/apache/lucene/luke/app/AbstractHandler.java
+++ b/lucene/luke/src/java/org/apache/lucene/luke/app/AbstractHandler.java
@@ -20,7 +20,8 @@ package org.apache.lucene.luke.app;
import java.lang.invoke.MethodHandles;
import java.util.ArrayList;
import java.util.List;
-import org.apache.logging.log4j.Logger;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import org.apache.lucene.luke.util.LoggerFactory;
/** Abstract handler class */
@@ -32,8 +33,8 @@ public abstract class AbstractHandler<T extends Observer> {
public void addObserver(T observer) {
observers.add(observer);
- if (log.isDebugEnabled()) {
- log.debug("{} registered.", observer.getClass().getName());
+ if (log.isLoggable(Level.FINE)) {
+ log.fine(observer.getClass().getName() + " registered.");
}
}
diff --git a/lucene/luke/src/java/org/apache/lucene/luke/app/IndexHandler.java b/lucene/luke/src/java/org/apache/lucene/luke/app/IndexHandler.java
index 46e2e3d..f35139e 100644
--- a/lucene/luke/src/java/org/apache/lucene/luke/app/IndexHandler.java
+++ b/lucene/luke/src/java/org/apache/lucene/luke/app/IndexHandler.java
@@ -21,7 +21,8 @@ import java.io.IOException;
import java.lang.invoke.MethodHandles;
import java.nio.file.NoSuchFileException;
import java.util.Objects;
-import org.apache.logging.log4j.Logger;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.luke.app.desktop.PreferencesFactory;
import org.apache.lucene.luke.app.desktop.util.MessageUtils;
@@ -75,19 +76,19 @@ public final class IndexHandler extends AbstractHandler<IndexObserver> {
try {
reader = IndexUtils.openIndex(indexPath, dirImpl);
} catch (NoSuchFileException e) {
- log.error("Error opening index", e);
+ log.log(Level.SEVERE, "Error opening index", e);
try {
// remove the non-existing index path from history.
PreferencesFactory.getInstance().removeHistory(indexPath);
} catch (IOException ioe) {
- log.error("Preference file is deleted?", ioe);
+ log.log(Level.SEVERE, "Preference file is deleted?", ioe);
}
throw new LukeException(
MessageUtils.getLocalizedMessage(
"openindex.message.index_path_does_not_exist", indexPath),
e);
} catch (Exception e) {
- log.error("Error opening index", e);
+ log.log(Level.SEVERE, "Error opening index", e);
throw new LukeException(
MessageUtils.getLocalizedMessage("openindex.message.index_path_invalid", indexPath), e);
}
diff --git a/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/LukeMain.java b/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/LukeMain.java
index 78c5254..f64ec18 100644
--- a/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/LukeMain.java
+++ b/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/LukeMain.java
@@ -22,10 +22,10 @@ import static org.apache.lucene.luke.app.desktop.util.ExceptionHandler.handle;
import java.awt.GraphicsEnvironment;
import java.io.IOException;
import java.lang.invoke.MethodHandles;
-import java.nio.file.FileSystems;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.UIManager;
-import org.apache.logging.log4j.Logger;
import org.apache.lucene.luke.app.desktop.components.LukeWindowProvider;
import org.apache.lucene.luke.app.desktop.components.dialog.menubar.OpenIndexDialogFactory;
import org.apache.lucene.luke.app.desktop.util.DialogOpener;
@@ -36,15 +36,8 @@ import org.apache.lucene.luke.util.LoggerFactory;
/** Entry class for desktop Luke */
public class LukeMain {
- public static final String LOG_FILE =
- System.getProperty("user.home")
- + FileSystems.getDefault().getSeparator()
- + ".luke.d"
- + FileSystems.getDefault().getSeparator()
- + "luke.log";
-
static {
- LoggerFactory.initGuiLogging(LOG_FILE);
+ LoggerFactory.initGuiLogging();
}
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@@ -77,7 +70,7 @@ public class LukeMain {
(factory) -> {});
} catch (IOException e) {
messageBroker.showUnknownErrorMessage();
- log.error("Cannot initialize components.", e);
+ log.log(Level.SEVERE, "Cannot initialize components.", e);
}
}
diff --git a/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/LogsPanelProvider.java b/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/LogsPanelProvider.java
index 1f6bcf1..26bf9fb 100644
--- a/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/LogsPanelProvider.java
+++ b/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/LogsPanelProvider.java
@@ -17,24 +17,28 @@
package org.apache.lucene.luke.app.desktop.components;
-import java.awt.BorderLayout;
-import java.awt.FlowLayout;
-import javax.swing.BorderFactory;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.JScrollPane;
-import javax.swing.JTextArea;
-import org.apache.lucene.luke.app.desktop.LukeMain;
+import java.awt.*;
+import java.awt.event.HierarchyEvent;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.Locale;
+import java.util.Objects;
+import java.util.function.Function;
+import java.util.logging.Level;
+import java.util.stream.Collectors;
+import javax.swing.*;
import org.apache.lucene.luke.app.desktop.util.MessageUtils;
+import org.apache.lucene.luke.util.CircularLogBufferHandler;
+import org.apache.lucene.luke.util.LoggerFactory;
/** Provider of the Logs panel */
public final class LogsPanelProvider {
- private final JTextArea logTextArea;
-
- public LogsPanelProvider(JTextArea logTextArea) {
- this.logTextArea = logTextArea;
- }
+ public LogsPanelProvider() {}
public JPanel get() {
JPanel panel = new JPanel(new BorderLayout());
@@ -43,14 +47,107 @@ public final class LogsPanelProvider {
JPanel header = new JPanel(new FlowLayout(FlowLayout.LEADING));
header.setOpaque(false);
- header.add(new JLabel(MessageUtils.getLocalizedMessage("logs.label.see_also")));
+ header.add(new JLabel(MessageUtils.getLocalizedMessage("logs.label.level")));
- JLabel logPathLabel = new JLabel(LukeMain.LOG_FILE);
- header.add(logPathLabel);
+ JComboBox<Level> logFilter =
+ new JComboBox<>(
+ new Level[] {
+ Level.FINEST,
+ Level.FINER,
+ Level.FINE,
+ Level.CONFIG,
+ Level.INFO,
+ Level.WARNING,
+ Level.SEVERE,
+ Level.OFF
+ });
+ logFilter.setEditable(false);
+ logFilter.setSelectedItem(Level.INFO);
+ header.add(logFilter);
- panel.add(header, BorderLayout.PAGE_START);
+ var logTextArea = createLogPanel(logFilter);
+ panel.add(header, BorderLayout.PAGE_START);
panel.add(new JScrollPane(logTextArea), BorderLayout.CENTER);
return panel;
}
+
+ /** Prepare the component responsible for displaying logs. */
+ private JTextArea createLogPanel(JComboBox<Level> logFilter) {
+ JTextArea logTextArea = new JTextArea();
+ logTextArea.setEditable(false);
+
+ class LogRecordFormatter
+ implements Function<CircularLogBufferHandler.ImmutableLogRecord, String> {
+ @Override
+ public String apply(CircularLogBufferHandler.ImmutableLogRecord record) {
+ return String.format(
+ Locale.ROOT,
+ "%s [%s] %s: %s",
+ DateTimeFormatter.ofPattern("HH:mm:ss", Locale.ROOT)
+ .format(record.getInstant().atZone(ZoneId.systemDefault())),
+ record.getLevel(),
+ record.getLoggerName(),
+ record.getMessage()
+ + (record.getThrown() == null ? "" : "\n" + toString(record.getThrown())));
+ }
+
+ private String toString(Throwable t) {
+ try (StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw)) {
+ t.printStackTrace(pw);
+ pw.flush();
+ return sw.toString();
+ } catch (IOException e) {
+ return "Could not dump stack trace: " + e.getMessage();
+ }
+ }
+ }
+
+ // Hook into live data from the circular log buffer and update the initial state.
+ Function<CircularLogBufferHandler.ImmutableLogRecord, String> formatter =
+ new LogRecordFormatter();
+ CircularLogBufferHandler.LogUpdateListener updater =
+ records -> {
+ // Create an immutable copy of the logs to display in the gui thread.
+ ArrayList<CircularLogBufferHandler.ImmutableLogRecord> clonedCopy =
+ new ArrayList<>(records);
+ SwingUtilities.invokeLater(
+ () -> {
+ Level level = (Level) Objects.requireNonNull(logFilter.getSelectedItem());
+
+ String logContent =
+ clonedCopy.stream()
+ .filter(record -> record.getLevel().intValue() > level.intValue())
+ .map(formatter::apply)
+ .collect(Collectors.joining("\n"));
+
+ logTextArea.setText(logContent);
+ });
+ };
+
+ var logBuffer = Objects.requireNonNull(LoggerFactory.circularBuffer);
+
+ // Update state on filter change.
+ logFilter.addActionListener(
+ e -> {
+ updater.accept(logBuffer.getLogRecords());
+ });
+
+ // Subscribe to log events and update state only when actually displayed.
+ logTextArea.addHierarchyListener(
+ (HierarchyEvent e) -> {
+ if (e.getComponent() == logTextArea
+ && (e.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0) {
+ if (logTextArea.isDisplayable()) {
+ logBuffer.addUpdateListener(updater);
+ updater.accept(logBuffer.getLogRecords());
+ } else {
+ logBuffer.removeUpdateListener(updater);
+ }
+ }
+ });
+
+ return logTextArea;
+ }
}
diff --git a/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/LukeWindowProvider.java b/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/LukeWindowProvider.java
index bbea489..a7a46a8 100644
--- a/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/LukeWindowProvider.java
+++ b/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/LukeWindowProvider.java
@@ -17,22 +17,9 @@
package org.apache.lucene.luke.app.desktop.components;
-import java.awt.BorderLayout;
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.FlowLayout;
-import java.awt.GridBagConstraints;
-import java.awt.GridBagLayout;
-import java.awt.GridLayout;
+import java.awt.*;
import java.io.IOException;
-import javax.swing.BorderFactory;
-import javax.swing.JFrame;
-import javax.swing.JLabel;
-import javax.swing.JMenuBar;
-import javax.swing.JPanel;
-import javax.swing.JTabbedPane;
-import javax.swing.JTextArea;
-import javax.swing.WindowConstants;
+import javax.swing.*;
import org.apache.lucene.luke.app.DirectoryHandler;
import org.apache.lucene.luke.app.DirectoryObserver;
import org.apache.lucene.luke.app.IndexHandler;
@@ -44,7 +31,6 @@ import org.apache.lucene.luke.app.desktop.PreferencesFactory;
import org.apache.lucene.luke.app.desktop.util.FontUtils;
import org.apache.lucene.luke.app.desktop.util.ImageUtils;
import org.apache.lucene.luke.app.desktop.util.MessageUtils;
-import org.apache.lucene.luke.app.desktop.util.TextAreaAppender;
import org.apache.lucene.util.Version;
/** Provider of the root window */
@@ -74,14 +60,9 @@ public final class LukeWindowProvider implements LukeWindowOperator {
private JFrame frame = new JFrame();
public LukeWindowProvider() throws IOException {
- // prepare log4j appender for Logs tab.
- JTextArea logTextArea = new JTextArea();
- logTextArea.setEditable(false);
- TextAreaAppender.setTextArea(logTextArea);
-
this.prefs = PreferencesFactory.getInstance();
this.menuBar = new MenuBarProvider().get();
- this.tabbedPane = new TabbedPaneProvider(logTextArea).get();
+ this.tabbedPane = new TabbedPaneProvider().get();
this.messageBroker = MessageBroker.getInstance();
this.tabSwitcher = TabSwitcherProxy.getInstance();
diff --git a/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/TabbedPaneProvider.java b/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/TabbedPaneProvider.java
index a64d89e..83468ab 100644
--- a/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/TabbedPaneProvider.java
+++ b/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/TabbedPaneProvider.java
@@ -20,7 +20,6 @@ package org.apache.lucene.luke.app.desktop.components;
import java.io.IOException;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
-import javax.swing.JTextArea;
import org.apache.lucene.luke.app.DirectoryHandler;
import org.apache.lucene.luke.app.DirectoryObserver;
import org.apache.lucene.luke.app.IndexHandler;
@@ -35,7 +34,7 @@ public final class TabbedPaneProvider implements TabSwitcherProxy.TabSwitcher {
private final MessageBroker messageBroker;
- private final JTabbedPane tabbedPane = new JTabbedPane();
+ private final JTabbedPane tabbedPane;
private final JPanel overviewPanel;
@@ -49,13 +48,15 @@ public final class TabbedPaneProvider implements TabSwitcherProxy.TabSwitcher {
private final JPanel logsPanel;
- public TabbedPaneProvider(JTextArea logTextArea) throws IOException {
+ public TabbedPaneProvider() throws IOException {
+ this.tabbedPane = new JTabbedPane();
+
this.overviewPanel = new OverviewPanelProvider().get();
this.documentsPanel = new DocumentsPanelProvider().get();
this.searchPanel = new SearchPanelProvider().get();
this.analysisPanel = new AnalysisPanelProvider().get();
this.commitsPanel = new CommitsPanelProvider().get();
- this.logsPanel = new LogsPanelProvider(logTextArea).get();
+ this.logsPanel = new LogsPanelProvider().get();
this.messageBroker = MessageBroker.getInstance();
diff --git a/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/dialog/documents/AddDocumentDialogFactory.java b/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/dialog/documents/AddDocumentDialogFactory.java
index 535dcaf..723cd21 100644
--- a/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/dialog/documents/AddDocumentDialogFactory.java
+++ b/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/dialog/documents/AddDocumentDialogFactory.java
@@ -33,6 +33,8 @@ import java.io.IOException;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Constructor;
import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import javax.swing.BorderFactory;
@@ -51,7 +53,6 @@ import javax.swing.ListSelectionModel;
import javax.swing.UIManager;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellRenderer;
-import org.apache.logging.log4j.Logger;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
@@ -399,15 +400,15 @@ public final class AddDocumentDialogFactory
doc.add(toIndexableField(nf));
}
} catch (NumberFormatException ex) {
- log.error("Error converting field value", e);
+ log.log(Level.SEVERE, "Error converting field value", e);
throw new LukeException("Invalid value: " + ex.getMessage(), ex);
} catch (Exception ex) {
- log.error("Error converting field value", e);
+ log.log(Level.SEVERE, "Error converting field value", e);
throw new LukeException(ex.getMessage(), ex);
}
addDocument(doc);
- log.info("Added document: {}", doc);
+ log.info("Added document: " + doc);
}
@SuppressWarnings("unchecked")
diff --git a/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/dialog/menubar/CheckIndexDialogFactory.java b/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/dialog/menubar/CheckIndexDialogFactory.java
index ba058c5..cd05bed 100644
--- a/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/dialog/menubar/CheckIndexDialogFactory.java
+++ b/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/dialog/menubar/CheckIndexDialogFactory.java
@@ -29,6 +29,8 @@ import java.io.IOException;
import java.lang.invoke.MethodHandles;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
@@ -39,7 +41,6 @@ import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JTextArea;
import javax.swing.SwingWorker;
-import org.apache.logging.log4j.Logger;
import org.apache.lucene.index.CheckIndex;
import org.apache.lucene.luke.app.DirectoryHandler;
import org.apache.lucene.luke.app.DirectoryObserver;
@@ -304,7 +305,7 @@ public final class CheckIndexDialogFactory implements DialogOpener.DialogFactory
}
status = st;
} catch (Exception e) {
- log.error("Error checking index", e);
+ log.log(Level.SEVERE, "Error checking index", e);
statusLbl.setText(MessageUtils.getLocalizedMessage("message.error.unknown"));
}
}
diff --git a/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/dialog/menubar/CreateIndexDialogFactory.java b/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/dialog/menubar/CreateIndexDialogFactory.java
index 995162e..223fc4f 100644
--- a/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/dialog/menubar/CreateIndexDialogFactory.java
+++ b/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/dialog/menubar/CreateIndexDialogFactory.java
@@ -35,6 +35,8 @@ import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
@@ -47,7 +49,6 @@ import javax.swing.JSeparator;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingWorker;
-import org.apache.logging.log4j.Logger;
import org.apache.lucene.luke.app.IndexHandler;
import org.apache.lucene.luke.app.desktop.Preferences;
import org.apache.lucene.luke.app.desktop.PreferencesFactory;
@@ -337,7 +338,7 @@ public class CreateIndexDialogFactory implements DialogOpener.DialogFactory {
IOException ex2) {
}
- log.error("Cannot create index", ex);
+ log.log(Level.SEVERE, "Cannot create index", ex);
String message = "See Logs tab or log file for more details.";
JOptionPane.showMessageDialog(
dialog, message, "Cannot create index", JOptionPane.ERROR_MESSAGE);
diff --git a/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/dialog/menubar/ExportTermsDialogFactory.java b/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/dialog/menubar/ExportTermsDialogFactory.java
index 87377e3..3bf84a2 100644
--- a/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/dialog/menubar/ExportTermsDialogFactory.java
+++ b/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/dialog/menubar/ExportTermsDialogFactory.java
@@ -31,6 +31,8 @@ import java.lang.invoke.MethodHandles;
import java.util.Arrays;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import java.util.stream.Stream;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
@@ -42,7 +44,6 @@ import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingWorker;
-import org.apache.logging.log4j.Logger;
import org.apache.lucene.luke.app.IndexHandler;
import org.apache.lucene.luke.app.IndexObserver;
import org.apache.lucene.luke.app.LukeState;
@@ -249,11 +250,11 @@ public final class ExportTermsDialogFactory implements DialogOpener.DialogFactor
try {
filename = toolsModel.exportTerms(directory, field, selectedDelimiter);
} catch (LukeException e) {
- log.error("Error while exporting terms from field {}", field, e);
+ log.log(Level.SEVERE, "Error while exporting terms from field " + field, e);
statusLbl.setText(
MessageUtils.getLocalizedMessage("export.terms.label.error", e.getMessage()));
} catch (Exception e) {
- log.error("Error while exporting terms from field {}", field, e);
+ log.log(Level.SEVERE, "Error while exporting terms from field " + field, e);
statusLbl.setText(MessageUtils.getLocalizedMessage("message.error.unknown"));
throw e;
} finally {
diff --git a/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/dialog/menubar/OpenIndexDialogFactory.java b/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/dialog/menubar/OpenIndexDialogFactory.java
index a523cd4..30e3d0b 100644
--- a/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/dialog/menubar/OpenIndexDialogFactory.java
+++ b/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/dialog/menubar/OpenIndexDialogFactory.java
@@ -32,6 +32,8 @@ import java.nio.file.Paths;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
@@ -45,7 +47,6 @@ import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JSeparator;
-import org.apache.logging.log4j.Logger;
import org.apache.lucene.luke.app.DirectoryHandler;
import org.apache.lucene.luke.app.IndexHandler;
import org.apache.lucene.luke.app.desktop.Preferences;
@@ -345,7 +346,7 @@ public final class OpenIndexDialogFactory implements DialogOpener.DialogFactory
MessageUtils.getLocalizedMessage("message.error.unknown"),
"Unknown Error",
JOptionPane.ERROR_MESSAGE);
- log.error("Error opening index or directory", cause);
+ log.log(Level.SEVERE, "Error opening index or directory", cause);
}
}
diff --git a/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/util/ExceptionHandler.java b/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/util/ExceptionHandler.java
index 481047c..d02e452 100644
--- a/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/util/ExceptionHandler.java
+++ b/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/util/ExceptionHandler.java
@@ -18,7 +18,8 @@
package org.apache.lucene.luke.app.desktop.util;
import java.lang.invoke.MethodHandles;
-import org.apache.logging.log4j.Logger;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import org.apache.lucene.luke.app.desktop.MessageBroker;
import org.apache.lucene.luke.models.LukeException;
import org.apache.lucene.luke.util.LoggerFactory;
@@ -32,10 +33,10 @@ public final class ExceptionHandler {
if (t instanceof LukeException) {
Throwable cause = t.getCause();
String message = (cause == null) ? t.getMessage() : t.getMessage() + " " + cause.getMessage();
- log.warn("Uncaught LukeException", t);
+ log.log(Level.WARNING, "Uncaught LukeException", t);
messageBroker.showStatusMessage(message);
} else {
- log.error("Uncaught Exception", t);
+ log.log(Level.SEVERE, "Uncaught Exception", t);
messageBroker.showUnknownErrorMessage();
}
}
diff --git a/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/util/TextAreaAppender.java b/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/util/TextAreaAppender.java
deleted file mode 100644
index 3d6964a..0000000
--- a/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/util/TextAreaAppender.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.lucene.luke.app.desktop.util;
-
-import java.io.Serializable;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-import javax.swing.JTextArea;
-import javax.swing.SwingUtilities;
-import org.apache.logging.log4j.core.Appender;
-import org.apache.logging.log4j.core.Core;
-import org.apache.logging.log4j.core.Filter;
-import org.apache.logging.log4j.core.LogEvent;
-import org.apache.logging.log4j.core.StringLayout;
-import org.apache.logging.log4j.core.appender.AbstractAppender;
-import org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender;
-import org.apache.logging.log4j.core.config.Property;
-import org.apache.logging.log4j.core.config.plugins.Plugin;
-import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
-
-/** Log appender for text areas */
-@Plugin(
- name = "TextArea",
- category = Core.CATEGORY_NAME,
- elementType = Appender.ELEMENT_TYPE,
- printObject = true)
-public final class TextAreaAppender extends AbstractAppender {
-
- private static JTextArea textArea;
-
- private static final ReadWriteLock rwLock = new ReentrantReadWriteLock();
- private static final Lock readLock = rwLock.readLock();
- private static final Lock writeLock = rwLock.writeLock();
-
- protected TextAreaAppender(
- String name,
- Filter filter,
- org.apache.logging.log4j.core.Layout<? extends Serializable> layout,
- final boolean ignoreExceptions) {
- super(name, filter, layout, ignoreExceptions, Property.EMPTY_ARRAY);
- }
-
- public static void setTextArea(JTextArea ta) {
- writeLock.lock();
- try {
- if (textArea != null) {
- throw new IllegalStateException("TextArea already set.");
- }
- textArea = ta;
- } finally {
- writeLock.unlock();
- }
- }
-
- @Override
- public void append(LogEvent event) {
- readLock.lock();
- try {
- if (textArea == null) {
- // just ignore any events logged before the area is available
- return;
- }
-
- final String message = ((StringLayout) getLayout()).toSerializable(event);
- SwingUtilities.invokeLater(
- () -> {
- textArea.append(message);
- });
- } finally {
- readLock.unlock();
- }
- }
-
- /**
- * Builds TextAreaAppender instances.
- *
- * @param <B> The type to build
- */
- public static class Builder<B extends Builder<B>> extends AbstractOutputStreamAppender.Builder<B>
- implements org.apache.logging.log4j.core.util.Builder<TextAreaAppender> {
-
- @Override
- public TextAreaAppender build() {
- return new TextAreaAppender(getName(), getFilter(), getOrCreateLayout(), true);
- }
- }
-
- @PluginBuilderFactory
- public static <B extends Builder<B>> B newBuilder() {
- return new Builder<B>().asBuilder();
- }
-}
diff --git a/lucene/luke/src/java/org/apache/lucene/luke/models/commits/CommitsImpl.java b/lucene/luke/src/java/org/apache/lucene/luke/models/commits/CommitsImpl.java
index 59b50a2..a103eee 100644
--- a/lucene/luke/src/java/org/apache/lucene/luke/models/commits/CommitsImpl.java
+++ b/lucene/luke/src/java/org/apache/lucene/luke/models/commits/CommitsImpl.java
@@ -26,8 +26,8 @@ import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.TreeMap;
+import java.util.logging.Logger;
import java.util.stream.Collectors;
-import org.apache.logging.log4j.Logger;
import org.apache.lucene.codecs.Codec;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexCommit;
@@ -98,7 +98,7 @@ public final class CommitsImpl extends LukeModel implements Commits {
if (ic == null) {
String msg = String.format(Locale.ENGLISH, "Commit generation %d not exists.", commitGen);
- log.warn(msg);
+ log.warning(msg);
return Optional.empty();
}
@@ -111,7 +111,7 @@ public final class CommitsImpl extends LukeModel implements Commits {
if (ic == null) {
String msg = String.format(Locale.ENGLISH, "Commit generation %d not exists.", commitGen);
- log.warn(msg);
+ log.warning(msg);
return Collections.emptyList();
}
diff --git a/lucene/luke/src/java/org/apache/lucene/luke/models/documents/DocumentsImpl.java b/lucene/luke/src/java/org/apache/lucene/luke/models/documents/DocumentsImpl.java
index 84daec9..9e36d4f 100644
--- a/lucene/luke/src/java/org/apache/lucene/luke/models/documents/DocumentsImpl.java
+++ b/lucene/luke/src/java/org/apache/lucene/luke/models/documents/DocumentsImpl.java
@@ -25,7 +25,7 @@ import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.Optional;
-import org.apache.logging.log4j.Logger;
+import java.util.logging.Logger;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.FieldInfo;
import org.apache.lucene.index.IndexReader;
@@ -80,7 +80,7 @@ public final class DocumentsImpl extends LukeModel implements Documents {
@Override
public List<DocumentField> getDocumentFields(int docid) {
if (!isLive(docid)) {
- log.info("Doc #{} was deleted", docid);
+ log.info("Doc #" + docid + " was deleted");
return Collections.emptyList();
}
@@ -126,7 +126,7 @@ public final class DocumentsImpl extends LukeModel implements Documents {
// no such field?
resetCurrentField();
resetTermsIterator();
- log.warn("Terms not available for field: {}.", field);
+ log.warning("Terms not available for field: " + field);
return Optional.empty();
} else {
setCurrentField(field);
@@ -135,7 +135,7 @@ public final class DocumentsImpl extends LukeModel implements Documents {
if (tenum.next() == null) {
// no term available for this field
resetTermsIterator();
- log.warn("No term available for field: {}.", field);
+ log.warning("No term available for field: " + field);
return Optional.empty();
} else {
return Optional.of(new Term(curField, tenum.term()));
@@ -156,7 +156,7 @@ public final class DocumentsImpl extends LukeModel implements Documents {
public Optional<Term> nextTerm() {
if (tenum == null) {
// terms enum not initialized
- log.warn("Terms enum un-positioned.");
+ log.warning("Terms enum un-positioned.");
return Optional.empty();
}
@@ -164,7 +164,7 @@ public final class DocumentsImpl extends LukeModel implements Documents {
if (tenum.next() == null) {
// end of the iterator
resetTermsIterator();
- log.info("Reached the end of the term iterator for field: {}.", curField);
+ log.info("Reached the end of the term iterator for field: " + curField);
return Optional.empty();
} else {
@@ -186,7 +186,7 @@ public final class DocumentsImpl extends LukeModel implements Documents {
if (curField == null) {
// field is not selected
- log.warn("Field not selected.");
+ log.warning("Field not selected.");
return Optional.empty();
}
@@ -197,7 +197,7 @@ public final class DocumentsImpl extends LukeModel implements Documents {
if (tenum.seekCeil(new BytesRef(termText)) == TermsEnum.SeekStatus.END) {
// reached to the end of the iterator
resetTermsIterator();
- log.info("Reached the end of the term iterator for field: {}.", curField);
+ log.info("Reached the end of the term iterator for field: " + curField);
return Optional.empty();
} else {
return Optional.of(new Term(curField, tenum.term()));
@@ -216,7 +216,7 @@ public final class DocumentsImpl extends LukeModel implements Documents {
public Optional<Integer> firstTermDoc() {
if (tenum == null) {
// terms enum is not set
- log.warn("Terms enum un-positioned.");
+ log.warning("Terms enum un-positioned.");
return Optional.empty();
}
@@ -226,10 +226,11 @@ public final class DocumentsImpl extends LukeModel implements Documents {
if (penum.nextDoc() == PostingsEnum.NO_MORE_DOCS) {
// no docs available for this term
resetPostingsIterator();
- log.warn(
- "No docs available for term: {} in field: {}.",
- BytesRefUtils.decode(tenum.term()),
- curField);
+ log.warning(
+ "No docs available for term: "
+ + BytesRefUtils.decode(tenum.term())
+ + " in field: "
+ + curField);
return Optional.empty();
} else {
return Optional.of(penum.docID());
@@ -245,7 +246,7 @@ public final class DocumentsImpl extends LukeModel implements Documents {
public Optional<Integer> nextTermDoc() {
if (penum == null) {
// postings enum is not initialized
- log.warn("Postings enum un-positioned for field: {}.", curField);
+ log.warning("Postings enum un-positioned for field: " + curField);
return Optional.empty();
}
@@ -253,12 +254,11 @@ public final class DocumentsImpl extends LukeModel implements Documents {
if (penum.nextDoc() == PostingsEnum.NO_MORE_DOCS) {
// end of the iterator
resetPostingsIterator();
- if (log.isInfoEnabled()) {
- log.info(
- "Reached the end of the postings iterator for term: {} in field: {}",
- BytesRefUtils.decode(tenum.term()),
- curField);
- }
+ log.info(
+ "Reached the end of the postings iterator for term: "
+ + BytesRefUtils.decode(tenum.term())
+ + " in field: "
+ + curField);
return Optional.empty();
} else {
return Optional.of(penum.docID());
@@ -274,7 +274,7 @@ public final class DocumentsImpl extends LukeModel implements Documents {
public List<TermPosting> getTermPositions() {
if (penum == null) {
// postings enum is not initialized
- log.warn("Postings enum un-positioned for field: {}.", curField);
+ log.warning("Postings enum un-positioned for field: " + curField);
return Collections.emptyList();
}
@@ -305,7 +305,7 @@ public final class DocumentsImpl extends LukeModel implements Documents {
public Optional<Integer> getDocFreq() {
if (tenum == null) {
// terms enum is not initialized
- log.warn("Terms enum un-positioned for field: {}.", curField);
+ log.warning("Terms enum un-positioned for field: " + curField);
return Optional.empty();
}
diff --git a/lucene/luke/src/java/org/apache/lucene/luke/models/documents/TermVectorsAdapter.java b/lucene/luke/src/java/org/apache/lucene/luke/models/documents/TermVectorsAdapter.java
index 64d8552..bfdd227 100644
--- a/lucene/luke/src/java/org/apache/lucene/luke/models/documents/TermVectorsAdapter.java
+++ b/lucene/luke/src/java/org/apache/lucene/luke/models/documents/TermVectorsAdapter.java
@@ -22,8 +22,9 @@ import java.lang.invoke.MethodHandles;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.Locale;
import java.util.Objects;
-import org.apache.logging.log4j.Logger;
+import java.util.logging.Logger;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Terms;
import org.apache.lucene.index.TermsEnum;
@@ -53,7 +54,10 @@ final class TermVectorsAdapter {
Terms termVector = reader.getTermVector(docid, field);
if (termVector == null) {
// no term vector available
- log.warn("No term vector indexed for doc: #{} and field: {}", docid, field);
+ log.warning(
+ () ->
+ String.format(
+ Locale.ROOT, "No term vector indexed for doc: #%s and field: %s", docid, field));
return Collections.emptyList();
}
diff --git a/lucene/luke/src/java/org/apache/lucene/luke/models/search/SearchImpl.java b/lucene/luke/src/java/org/apache/lucene/luke/models/search/SearchImpl.java
index a1122a3..c4b9629 100644
--- a/lucene/luke/src/java/org/apache/lucene/luke/models/search/SearchImpl.java
+++ b/lucene/luke/src/java/org/apache/lucene/luke/models/search/SearchImpl.java
@@ -30,8 +30,8 @@ import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
+import java.util.logging.Logger;
import java.util.stream.Collectors;
-import org.apache.logging.log4j.Logger;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.index.DocValuesType;
import org.apache.lucene.index.FieldInfo;
@@ -230,7 +230,7 @@ public final class SearchImpl extends LukeModel implements Search {
} else if (type == Float.class || type == Double.class) {
pc = new PointsConfig(NumberFormat.getNumberInstance(Locale.ROOT), type);
} else {
- log.warn(
+ log.warning(
String.format(Locale.ENGLISH, "Ignored invalid number type: %s.", type.getName()));
continue;
}
@@ -344,7 +344,7 @@ public final class SearchImpl extends LukeModel implements Search {
if (totalHits.value == 0
|| (totalHits.relation == TotalHits.Relation.EQUAL_TO
&& currentPage * pageSize >= totalHits.value)) {
- log.warn("No more next search results are available.");
+ log.warning("No more next search results are available.");
return Optional.empty();
}
@@ -375,7 +375,7 @@ public final class SearchImpl extends LukeModel implements Search {
currentPage -= 1;
if (currentPage < 0) {
- log.warn("No more previous search results are available.");
+ log.warning("No more previous search results are available.");
return Optional.empty();
}
@@ -462,7 +462,7 @@ public final class SearchImpl extends LukeModel implements Search {
Objects.requireNonNull(type);
List<SortField> candidates = guessSortTypes(name);
if (candidates.isEmpty()) {
- log.warn(String.format(Locale.ENGLISH, "No available sort types for: %s", name));
+ log.warning(String.format(Locale.ENGLISH, "No available sort types for: %s", name));
return Optional.empty();
}
diff --git a/lucene/luke/src/java/org/apache/lucene/luke/models/util/IndexUtils.java b/lucene/luke/src/java/org/apache/lucene/luke/models/util/IndexUtils.java
index 27cd107..e616116 100644
--- a/lucene/luke/src/java/org/apache/lucene/luke/models/util/IndexUtils.java
+++ b/lucene/luke/src/java/org/apache/lucene/luke/models/util/IndexUtils.java
@@ -34,9 +34,10 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
-import org.apache.logging.log4j.Logger;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.core.WhitespaceAnalyzer;
import org.apache.lucene.codecs.CodecUtil;
@@ -84,7 +85,7 @@ public final class IndexUtils {
DirectoryReader dr = DirectoryReader.open(dir);
readers.add(dr);
} catch (IOException e) {
- log.warn("Error opening directory", e);
+ log.log(Level.WARNING, "Error opening directory", e);
}
return FileVisitResult.CONTINUE;
}
@@ -94,14 +95,12 @@ public final class IndexUtils {
throw new RuntimeException("No valid directory at the location: " + indexPath);
}
- if (log.isInfoEnabled()) {
- log.info(
- String.format(
- Locale.ENGLISH,
- "IndexReaders (%d leaf readers) successfully opened. Index path=%s",
- readers.size(),
- indexPath));
- }
+ log.info(
+ String.format(
+ Locale.ENGLISH,
+ "IndexReaders (%d leaf readers) successfully opened. Index path=%s",
+ readers.size(),
+ indexPath));
if (readers.size() == 1) {
return readers.get(0);
@@ -134,11 +133,9 @@ public final class IndexUtils {
public static Directory openDirectory(String dirPath, String dirImpl) throws IOException {
final Path path = FileSystems.getDefault().getPath(Objects.requireNonNull(dirPath));
Directory dir = openDirectory(path, dirImpl);
- if (log.isInfoEnabled()) {
- log.info(
- String.format(
- Locale.ENGLISH, "DirectoryReader successfully opened. Directory path=%s", dirPath));
- }
+ log.info(
+ String.format(
+ Locale.ENGLISH, "DirectoryReader successfully opened. Directory path=%s", dirPath));
return dir;
}
@@ -161,7 +158,7 @@ public final class IndexUtils {
dir = (Directory) constr.newInstance(path, null);
}
} catch (Exception e) {
- log.warn("Invalid directory implementation class: {}", dirImpl, e);
+ log.log(Level.WARNING, "Invalid directory implementation class: " + dirImpl, e);
throw new IllegalArgumentException("Invalid directory implementation class: " + dirImpl);
}
}
@@ -180,7 +177,7 @@ public final class IndexUtils {
log.info("Directory successfully closed.");
}
} catch (IOException e) {
- log.error("Error closing directory", e);
+ log.log(Level.SEVERE, "Error closing directory", e);
}
}
@@ -201,7 +198,7 @@ public final class IndexUtils {
}
}
} catch (IOException e) {
- log.error("Error closing index reader", e);
+ log.log(Level.SEVERE, "Error closing index reader", e);
}
}
diff --git a/lucene/luke/src/java/org/apache/lucene/luke/models/util/twentynewsgroups/MessageFilesParser.java b/lucene/luke/src/java/org/apache/lucene/luke/models/util/twentynewsgroups/MessageFilesParser.java
index c5b5d0d..41db69b 100644
--- a/lucene/luke/src/java/org/apache/lucene/luke/models/util/twentynewsgroups/MessageFilesParser.java
+++ b/lucene/luke/src/java/org/apache/lucene/luke/models/util/twentynewsgroups/MessageFilesParser.java
@@ -28,7 +28,8 @@ import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.List;
-import org.apache.logging.log4j.Logger;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import org.apache.lucene.luke.util.LoggerFactory;
/**
@@ -56,10 +57,8 @@ public class MessageFilesParser extends SimpleFileVisitor<Path> {
messages.add(parse(file));
}
}
- } catch (
- @SuppressWarnings("unused")
- IOException e) {
- log.warn("Invalid file? {}", file);
+ } catch (IOException e) {
+ log.log(Level.WARNING, "Invalid file? " + file, e);
}
return FileVisitResult.CONTINUE;
}
diff --git a/lucene/luke/src/java/org/apache/lucene/luke/util/CircularLogBufferHandler.java b/lucene/luke/src/java/org/apache/lucene/luke/util/CircularLogBufferHandler.java
new file mode 100644
index 0000000..e0ad6f7
--- /dev/null
+++ b/lucene/luke/src/java/org/apache/lucene/luke/util/CircularLogBufferHandler.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.lucene.luke.util;
+
+import java.time.Instant;
+import java.util.ArrayDeque;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.function.Consumer;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+
+/** A {@link Handler} with a bounded buffer of recent log messages. */
+public class CircularLogBufferHandler extends Handler {
+ /** Provides an immutable clone of the required data from a {@link LogRecord} logged elsewhere. */
+ public static final class ImmutableLogRecord {
+ private final String loggerName;
+ private final Level level;
+ private final String message;
+ private final Throwable thrown;
+ private final Instant instant;
+
+ public ImmutableLogRecord(LogRecord record) {
+ this.loggerName = record.getLoggerName();
+ this.level = record.getLevel();
+ this.message = record.getMessage();
+ this.thrown = record.getThrown();
+ this.instant = record.getInstant();
+ }
+
+ public String getLoggerName() {
+ return loggerName;
+ }
+
+ public Level getLevel() {
+ return level;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public Throwable getThrown() {
+ return thrown;
+ }
+
+ public Instant getInstant() {
+ return instant;
+ }
+ }
+
+ /** Listeners receiving log state updates. */
+ public interface LogUpdateListener extends Consumer<Collection<ImmutableLogRecord>> {}
+
+ /** A bounded buffer of immutable log records that have been recently logged by the framework. */
+ private final ArrayDeque<ImmutableLogRecord> buffer = new ArrayDeque<>();
+
+ /**
+ * Listeners interested in receiving log state updates. At the moment listeners receive an
+ * iterable with all log records in the circular buffer. We could make it incremental for each
+ * consumer but for Luke it really doesn't matter since the rate of updates is very small.
+ */
+ private final List<LogUpdateListener> listeners = new CopyOnWriteArrayList<>();
+
+ @Override
+ public void publish(LogRecord record) {
+ synchronized (buffer) {
+ buffer.addLast(new ImmutableLogRecord(record));
+ listeners.forEach(c -> c.accept(buffer));
+ }
+ }
+
+ @Override
+ public void flush() {
+ // Ignore.
+ }
+
+ @Override
+ public void close() throws SecurityException {
+ // Ignore.
+ }
+
+ public void addUpdateListener(LogUpdateListener listener) {
+ listeners.add(listener);
+ }
+
+ public void removeUpdateListener(LogUpdateListener listener) {
+ listeners.remove(listener);
+ }
+
+ /** @return Return a clone of the buffered records so far. */
+ public Collection<ImmutableLogRecord> getLogRecords() {
+ synchronized (buffer) {
+ return new ArrayDeque<>(buffer);
+ }
+ }
+}
diff --git a/lucene/luke/src/java/org/apache/lucene/luke/util/LoggerFactory.java b/lucene/luke/src/java/org/apache/lucene/luke/util/LoggerFactory.java
index a1a9184..6f134a7 100644
--- a/lucene/luke/src/java/org/apache/lucene/luke/util/LoggerFactory.java
+++ b/lucene/luke/src/java/org/apache/lucene/luke/util/LoggerFactory.java
@@ -17,54 +17,28 @@
package org.apache.lucene.luke.util;
-import java.nio.charset.StandardCharsets;
-import org.apache.logging.log4j.Level;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.core.Appender;
-import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.core.appender.FileAppender;
-import org.apache.logging.log4j.core.config.Configurator;
-import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilder;
-import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilderFactory;
-import org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration;
-import org.apache.logging.log4j.core.layout.PatternLayout;
-import org.apache.lucene.luke.app.desktop.util.TextAreaAppender;
+import java.util.logging.Level;
+import java.util.logging.Logger;
-/** Logger factory. This programmatically configurates logger context (Appenders etc.) */
+/** Logger factory. This configures log interceptors for the GUI. */
public class LoggerFactory {
+ public static CircularLogBufferHandler circularBuffer;
- public static void initGuiLogging(String logFile) {
- ConfigurationBuilder<BuiltConfiguration> builder =
- ConfigurationBuilderFactory.newConfigurationBuilder();
- builder.add(builder.newRootLogger(Level.INFO));
- LoggerContext context = Configurator.initialize(builder.build());
+ public static void initGuiLogging() {
+ if (circularBuffer != null) {
+ throw new RuntimeException("Double-initialization?");
+ }
- PatternLayout layout =
- PatternLayout.newBuilder()
- .withPattern("[%d{ISO8601}] %5p (%F:%L) - %m%n")
- .withCharset(StandardCharsets.UTF_8)
- .build();
+ circularBuffer = new CircularLogBufferHandler();
+ circularBuffer.setLevel(Level.FINEST);
- Appender fileAppender =
- FileAppender.newBuilder()
- .setName("File")
- .setLayout(layout)
- .withFileName(logFile)
- .withAppend(false)
- .build();
- fileAppender.start();
-
- Appender textAreaAppender =
- TextAreaAppender.newBuilder().setName("TextArea").setLayout(layout).build();
- textAreaAppender.start();
-
- context.getRootLogger().addAppender(fileAppender);
- context.getRootLogger().addAppender(textAreaAppender);
- context.updateLoggers();
+ // Only capture events from Lucene logger hierarchy.
+ var luceneRoot = Logger.getLogger("org.apache.lucene");
+ luceneRoot.setLevel(Level.FINEST);
+ luceneRoot.addHandler(circularBuffer);
}
public static Logger getLogger(Class<?> clazz) {
- return LogManager.getLogger(clazz);
+ return Logger.getLogger(clazz.getName());
}
}
diff --git a/lucene/luke/src/resources/org/apache/lucene/luke/app/desktop/messages/messages.properties b/lucene/luke/src/resources/org/apache/lucene/luke/app/desktop/messages/messages.properties
index e814329..8e91e51 100644
--- a/lucene/luke/src/resources/org/apache/lucene/luke/app/desktop/messages/messages.properties
+++ b/lucene/luke/src/resources/org/apache/lucene/luke/app/desktop/messages/messages.properties
@@ -280,7 +280,7 @@ commits.label.files=Files
commits.label.segments=Segments (click rows for more details)
commits.label.segdetails=Segment details
# Logs
-logs.label.see_also=See also:
+logs.label.level=Log level:
# Help dialogs
help.fieldtype.TextField=A field that is indexed and tokenized, without term vectors.\n\n(Example Values)\n- Hello Lucene!
help.fieldtype.StringField=A field that is indexed but not tokenized: the entire String value is indexed as a single token.\n\n(Example Values)\n- Java
diff --git a/versions.lock b/versions.lock
index 80f63aa..87c5b3f 100644
--- a/versions.lock
+++ b/versions.lock
@@ -12,8 +12,6 @@ org.antlr:antlr4-runtime:4.5.1-1 (1 constraints: 6a05b240)
org.apache.commons:commons-compress:1.19 (1 constraints: df04fa30)
org.apache.httpcomponents:httpclient:4.5.13 (1 constraints: 3f054e3b)
org.apache.httpcomponents:httpcore:4.4.13 (1 constraints: 591016a2)
-org.apache.logging.log4j:log4j-api:2.15.0 (1 constraints: bb0e1f76)
-org.apache.logging.log4j:log4j-core:2.15.0 (1 constraints: 3a053e3b)
org.apache.opennlp:opennlp-tools:1.9.1 (1 constraints: 0d050c36)
org.carrot2:morfologik-fsa:2.1.8 (1 constraints: da0d9b36)
org.carrot2:morfologik-polish:2.1.8 (1 constraints: 0d050036)
diff --git a/versions.props b/versions.props
index 185bcfc..c010392 100644
--- a/versions.props
+++ b/versions.props
@@ -10,7 +10,6 @@ net.sourceforge.nekohtml:nekohtml=1.9.17
org.antlr:antlr4*=4.5.1-1
org.apache.commons:commons-compress=1.19
org.apache.httpcomponents:httpclient=4.5.13
-org.apache.logging.log4j:*=2.15.0
org.apache.opennlp:opennlp-tools=1.9.1
org.carrot2:morfologik-*=2.1.8
org.eclipse.jetty:*=9.4.41.v20210516