From 7d5a5691780ed8373e77641b4a08f18cba0b9fab Mon Sep 17 00:00:00 2001 From: jsimomaa Date: Fri, 2 Mar 2018 12:28:34 +0200 Subject: [PATCH] Logging configuration via SCL and UI & saving to ZIP-archive refs #7795 Change-Id: Ib8867aff85634d6a1ed6d2fe65da4e43818b83fc --- bundles/org.simantics.logging.ui/.classpath | 7 ++ bundles/org.simantics.logging.ui/.project | 28 ++++++ .../.settings/org.eclipse.jdt.core.prefs | 7 ++ .../META-INF/MANIFEST.MF | 20 ++++ .../org.simantics.logging.ui/build.properties | 7 ++ .../org.simantics.logging.ui/fragment.e4xmi | 37 +++++++ .../org.simantics.logging.ui/icons/bug.png | Bin 0 -> 774 bytes .../org.simantics.logging.ui/icons/error.png | Bin 0 -> 701 bytes .../icons/information.png | Bin 0 -> 778 bytes .../org.simantics.logging.ui/icons/page.png | Bin 0 -> 635 bytes .../icons/page_white_compressed.png | Bin 0 -> 724 bytes .../icons/page_white_edit.png | Bin 0 -> 618 bytes .../icons/text_align_left.png | Bin 0 -> 209 bytes .../icons/warning.png | Bin 0 -> 666 bytes bundles/org.simantics.logging.ui/plugin.xml | 14 +++ .../org/simantics/logging/ui/Activator.java | 30 ++++++ .../ui/handlers/SaveLogFilesHandler.java | 93 ++++++++++++++++++ .../handlers/SelectLoggingLevelHandler.java | 21 ++++ bundles/org.simantics.logging/.classpath | 7 ++ bundles/org.simantics.logging/.project | 33 +++++++ .../.settings/org.eclipse.jdt.core.prefs | 7 ++ .../META-INF/MANIFEST.MF | 16 +++ .../org.simantics.logging/build.properties | 7 ++ .../dbAndMetadataLogProvider.xml | 7 ++ .../logbackLogProvider.xml | 7 ++ .../scl/LoggingUtils.scl | 9 ++ .../logging/DBAndMetadataLogProvider.java | 60 +++++++++++ .../org/simantics/logging/LogCollector.java | 65 ++++++++++++ .../simantics/logging/LogConfigurator.java | 54 ++++++++++ .../org/simantics/logging/LogProvider.java | 9 ++ .../simantics/logging/LogbackLogProvider.java | 83 ++++++++++++++++ .../simantics/logging/internal/Activator.java | 30 ++++++ bundles/pom.xml | 2 + .../org.simantics.logging.feature/.project | 17 ++++ .../build.properties | 1 + .../org.simantics.logging.feature/feature.xml | 27 +++++ .../org.simantics.logging.ui.feature/.project | 17 ++++ .../build.properties | 1 + .../feature.xml | 31 ++++++ .../org.simantics.sdk.feature/feature.xml | 8 ++ features/pom.xml | 2 + 41 files changed, 764 insertions(+) create mode 100644 bundles/org.simantics.logging.ui/.classpath create mode 100644 bundles/org.simantics.logging.ui/.project create mode 100644 bundles/org.simantics.logging.ui/.settings/org.eclipse.jdt.core.prefs create mode 100644 bundles/org.simantics.logging.ui/META-INF/MANIFEST.MF create mode 100644 bundles/org.simantics.logging.ui/build.properties create mode 100644 bundles/org.simantics.logging.ui/fragment.e4xmi create mode 100644 bundles/org.simantics.logging.ui/icons/bug.png create mode 100644 bundles/org.simantics.logging.ui/icons/error.png create mode 100644 bundles/org.simantics.logging.ui/icons/information.png create mode 100644 bundles/org.simantics.logging.ui/icons/page.png create mode 100644 bundles/org.simantics.logging.ui/icons/page_white_compressed.png create mode 100644 bundles/org.simantics.logging.ui/icons/page_white_edit.png create mode 100644 bundles/org.simantics.logging.ui/icons/text_align_left.png create mode 100644 bundles/org.simantics.logging.ui/icons/warning.png create mode 100644 bundles/org.simantics.logging.ui/plugin.xml create mode 100644 bundles/org.simantics.logging.ui/src/org/simantics/logging/ui/Activator.java create mode 100644 bundles/org.simantics.logging.ui/src/org/simantics/logging/ui/handlers/SaveLogFilesHandler.java create mode 100644 bundles/org.simantics.logging.ui/src/org/simantics/logging/ui/handlers/SelectLoggingLevelHandler.java create mode 100644 bundles/org.simantics.logging/.classpath create mode 100644 bundles/org.simantics.logging/.project create mode 100644 bundles/org.simantics.logging/.settings/org.eclipse.jdt.core.prefs create mode 100644 bundles/org.simantics.logging/META-INF/MANIFEST.MF create mode 100644 bundles/org.simantics.logging/build.properties create mode 100644 bundles/org.simantics.logging/dbAndMetadataLogProvider.xml create mode 100644 bundles/org.simantics.logging/logbackLogProvider.xml create mode 100644 bundles/org.simantics.logging/scl/LoggingUtils.scl create mode 100644 bundles/org.simantics.logging/src/org/simantics/logging/DBAndMetadataLogProvider.java create mode 100644 bundles/org.simantics.logging/src/org/simantics/logging/LogCollector.java create mode 100644 bundles/org.simantics.logging/src/org/simantics/logging/LogConfigurator.java create mode 100644 bundles/org.simantics.logging/src/org/simantics/logging/LogProvider.java create mode 100644 bundles/org.simantics.logging/src/org/simantics/logging/LogbackLogProvider.java create mode 100644 bundles/org.simantics.logging/src/org/simantics/logging/internal/Activator.java create mode 100644 features/org.simantics.logging.feature/.project create mode 100644 features/org.simantics.logging.feature/build.properties create mode 100644 features/org.simantics.logging.feature/feature.xml create mode 100644 features/org.simantics.logging.ui.feature/.project create mode 100644 features/org.simantics.logging.ui.feature/build.properties create mode 100644 features/org.simantics.logging.ui.feature/feature.xml diff --git a/bundles/org.simantics.logging.ui/.classpath b/bundles/org.simantics.logging.ui/.classpath new file mode 100644 index 000000000..eca7bdba8 --- /dev/null +++ b/bundles/org.simantics.logging.ui/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/bundles/org.simantics.logging.ui/.project b/bundles/org.simantics.logging.ui/.project new file mode 100644 index 000000000..e5853c591 --- /dev/null +++ b/bundles/org.simantics.logging.ui/.project @@ -0,0 +1,28 @@ + + + org.simantics.logging.ui + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/bundles/org.simantics.logging.ui/.settings/org.eclipse.jdt.core.prefs b/bundles/org.simantics.logging.ui/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..0c68a61dc --- /dev/null +++ b/bundles/org.simantics.logging.ui/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/bundles/org.simantics.logging.ui/META-INF/MANIFEST.MF b/bundles/org.simantics.logging.ui/META-INF/MANIFEST.MF new file mode 100644 index 000000000..3f910c8e4 --- /dev/null +++ b/bundles/org.simantics.logging.ui/META-INF/MANIFEST.MF @@ -0,0 +1,20 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Ui +Bundle-SymbolicName: org.simantics.logging.ui;singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: org.simantics.logging.ui.Activator +Require-Bundle: javax.inject, + org.eclipse.osgi, + org.eclipse.jface, + org.eclipse.e4.ui.services, + org.eclipse.e4.core.di.annotations, + org.eclipse.core.runtime, + org.eclipse.ui.ide, + org.slf4j.api, + org.simantics.logging, + org.simantics.utils, + org.simantics.utils.ui +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +Import-Package: javax.annotation;version="1.2.0" +Bundle-ActivationPolicy: lazy diff --git a/bundles/org.simantics.logging.ui/build.properties b/bundles/org.simantics.logging.ui/build.properties new file mode 100644 index 000000000..7af290f32 --- /dev/null +++ b/bundles/org.simantics.logging.ui/build.properties @@ -0,0 +1,7 @@ +source.. = src/ +output.. = bin/ +bin.includes = plugin.xml,\ + META-INF/,\ + .,\ + icons/,\ + fragment.e4xmi diff --git a/bundles/org.simantics.logging.ui/fragment.e4xmi b/bundles/org.simantics.logging.ui/fragment.e4xmi new file mode 100644 index 000000000..cc14bb5f8 --- /dev/null +++ b/bundles/org.simantics.logging.ui/fragment.e4xmi @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bundles/org.simantics.logging.ui/icons/bug.png b/bundles/org.simantics.logging.ui/icons/bug.png new file mode 100644 index 0000000000000000000000000000000000000000..2d5fb90ec6ee08f53947e0266a87b03f75893446 GIT binary patch literal 774 zcmV+h1Nr=kP) zlgUq0Q544c8(ae&UR$8ps&snq6^bPY3v3xAmMW74Di$h~GCH6E3TaYs2#6A<7K*gC z777H71_Wa;(dfp+g-drPCSWu)#PInZi72LJ;o?i~$-U=y&UbQ89Dul3%3P+Axkzc* zbH-y;QF=hR{qLItf%ci2_&e5wNo0gnVatG?ul6Zw=o$I9Ljfn*ic3`U?>IfEim3g{ zujU&$-hy6wn;w(xme|zJm;lWJxtTFfM)q0`kX!Vu0+d${$}LCddK1<^htTe-fUYL3 zB`SdNsZD>RgvLj1<^@h6_+cDRK2Brcr2~>%$*5S)hyV33PV^teac3%|4lz@8p4?)5 z?t5o^?q+%^%)Yygo~I^U4VR!bTnWuE35hcWrfCDR3q+sxJ79e7Fg`&)RCqLA^2^y^ z0laVfadW90_Fz8Brm|r47sB^u1VgI>kanj)Z4`zMSfHlm8>CwXa$JVM`$2RrmZB-3 zN10m-!;BvH*Br3V8t`DH7m`jf#2upVDXl{5ff18_pzCPK1Zu$$CKKvd8FGeFf)+K<|x33pc7P&S#3GZT4mEw;nr(Ze*F z3&*?-4U-lm*#tber5 z%S_ceqB`b3ko6r~BbvDwdohTvP(3a(pq{x#T$yQsu#OKwEe}KuH^Mh@nxg_(Nw136 zq#a^3xNBke)In+!?qk3%4wB69{pF`Tzg`07*qoM6N<$ Eg55P&8UO$Q literal 0 HcmV?d00001 diff --git a/bundles/org.simantics.logging.ui/icons/error.png b/bundles/org.simantics.logging.ui/icons/error.png new file mode 100644 index 0000000000000000000000000000000000000000..c37bd062e60c3b38fc82e4d1f236a8ac2fae9d8c GIT binary patch literal 701 zcmV;u0z&N#0$9Ug7g~-`rQ^qx~m@y2OU8A z#zh~=7n#Z$Z*fx-GOtDf07cgx0suCz_W(2~Y(0tf@FX@P6EPuM_dgn$vj9LucO)%W zw%HgMW>=#oL>nZ>M&NEf08>)#)k<{$fCT_r>rPi=BV=hFh6WS^qqze>C6Ek}o{M5% za|@JGowu0t{&hgNzySHZxy@LTNh);YzZ2zSp_ zl$^T&Dnc|NLb&RD_!4>pt@VHdP)ZGER%5ZmWEe$lryR&y;2u^3cOkO4#6c%-(EY6a{600000NkvXXu0mjfxS2AI literal 0 HcmV?d00001 diff --git a/bundles/org.simantics.logging.ui/icons/information.png b/bundles/org.simantics.logging.ui/icons/information.png new file mode 100644 index 0000000000000000000000000000000000000000..12cd1aef900803abba99b26920337ec01ad5c267 GIT binary patch literal 778 zcmV+l1NHogP)BVme|mWaqy4$_pJm?y9KM{-*hp?1+Ey3e-CEDooTa!B;e(Q>TSF?bj>5At13y1p zriN3w3x~5SfZj{@J4M{kp{?=M_Lh2bV+5LH)Q)5W!-ePA$RgE1@5f1cyHki0Y}JyVEYZF(LD$xXlt$7A5CgE@ zpV-&l%vf;=5kZ2-2gi@Y6J&=cuwt>!vJ^#(&n|LcZyUzi6Duj$$hJ1s*HD-#;k-w@ zpdrwAuoDG_N2bvb07G$Zk*?Hc)JLtW4yqOnic_$zO7NZ#l>Fm){;fE?b$IbOaX2fe z0la4g0Dfw2xk7Wi7NapVD8YMPCZu?A1QCK*67dgsvRKBLFtrM>?$%&_lD1882mzdO zWPdw5KWw6IT`m1b_8=lS5jt8D3=RDa=&jWzR-)S@56WMslZ~mKu1)-wpXB>rNBQ>N zU#K`#1B&v|_AQK;7I~B}OdGiUT9LX>f0xm6<;LeP!=vFjPsUQF*wCJ*dO)4YBypgdiuF!=i@6Zyi7F|q#K zz?tlSZULa@t1D?$e;f@b36&N!V2mjOHw|*0)+jEP);68^d)m`eN0o>(5%D`Q(1;j>g@G;xlf`0VBQ`PFY?6)!N&f?*K}$p; zB!U=NBn{eB8${1}&-2_L*HuZp@ZP1@clS@cHp)4iM1ewzw59vko7eMM{e9z|%NNdX z0V;`?KKSzTCvTm5bc{L^CIKLUxc2X{i{ISz$8Sgf{q)1nXTP{`{s?9mQ$4&hPiKC- zY8q7(Y1Xu5iCf33=O4Vy(+|zQ?rW#gkKB0f%}?+6{G*qT22|DQB-73`YzA{N4W^=s zq0kQYcbtFfz zLz)H<&|z(Y4k zJ3A|*qoWOonz+4ZQ0KNhDB07SX1?#FrNy8%K)_l}y&kh`*KYdy`Y99&tgNgMLSSrc z?B?+B@HO@P-jS~z2Rgc6yy~Y~%>oJpBxsb$5<&nRLqiuR7K=@0SZj~jTs|sv_jWVX zGe?WflejOaq|Vec=s9+ahmXbyJ|T)Sl*?s82sr2H?Ce~HD5WI+Sz&tmWrN()wI2}+ zKqg92t*l^-#ae~;9%KFlWkmwnY=-UK`_|%ICZ#P1gdjK<2n38VXsuC7{WiU!fZFmm zW~Sda9(Qi@pxO}$ARY+;t##Ao27usOqNt7Hwq6K7G1il@xitj=LIM&{N&#SuX;x4x zmG6FhCg-$PI;hQ=;1iZ>F>^~@)IPi;l}fX?SZ!QiO=X<|pSVkNpJuLHzW(FT_~W-v z?vFpkyE>8ee4d=7wKauH5~dd_M7d2Aa=ICC{Nj7Blqv&DQEP#j_VeWV&WXL>c=LLK zsmYg^_JiDb;%U!UxO%qjFAvsDFj-kzT2$GbV(ZopPM$i$z`!7jvEk07BcC=6FMt4` z*0u3Sy`0b~%#(0000K literal 0 HcmV?d00001 diff --git a/bundles/org.simantics.logging.ui/icons/page_white_edit.png b/bundles/org.simantics.logging.ui/icons/page_white_edit.png new file mode 100644 index 0000000000000000000000000000000000000000..b93e77600def75c9a144d3d0a5088a62c02cbb0b GIT binary patch literal 618 zcmV-w0+s!VP)$>5Y&axjp2O=VLu>*f>1L;s0)kkvKC!*u?s6CVL=HJ6oP~pNfZc; zsKr=bq;7MITw8NXw{SZm%59TId2x_9BQ zV86`NuvGI!>o^V!Na!=$7GJE{Cq`b+XwknM{UcGHFTTfmuS+ zm-zYC!P3+zmY;SG$?!fYkOih`QYaLxyF}A86h$GGN}kFj)_o*0e zjPMP%zTG7FYMAfO2Nn1D`D0Cj?Wl>5q%@CE10nX)KxpNmwk+!IWkzywiYD( zqUXiYYIq3qcRyMGJ;IY`(Gz~E$J$zu2+R{)xGlE*88b3WK6V*J>}2iPY1HH|tER0W z_+^^FdppY?o)Gt5M2`%xwRDH@R3G}^i1l4|6uchm0X0f!@&YdVLB5K&dd7Rv{)DXX zt^&vP;}kqj3f>94j+4xd93>s|Q!Ezi>?r8(Il$P}PFxSqu{d*!Y%*#cX(R0f|Juz# z3o0_xI14Al->1uky@W-rCI_%l&>C#5QQ<|d}62BjvZR2H60wE-$h_H=O!(Kw&{=X`^_fnmU^23D6T z|NkHVz|K?O{7~QE-_Z@zCpI>Iv^P`}`P2Tg^~Il~8@dITHCPA-{a3!-)3Cjx%=yXx z_>8LclV7mqn+PY^{qor&o%8>H%d3``{~Y#6bGV5yoI2touNPXs5@;QRr>mdKI;Vst E04%Lf&j0`b literal 0 HcmV?d00001 diff --git a/bundles/org.simantics.logging.ui/icons/warning.png b/bundles/org.simantics.logging.ui/icons/warning.png new file mode 100644 index 0000000000000000000000000000000000000000..628cf2dae3d419ae220c8928ac71393b480745a3 GIT binary patch literal 666 zcmV;L0%iS)P)eOSYYtbpBV}~vsBnU!_?2tr-P=|^T zED%wc9ezHgW@NMb!^uT_|SvCpFLJylbx zY%bpaTGI8IYXMN$9w<3j9VkA~NYOKEQXsj?6a9_hcwfU$acAhJhB)zb_w@MVUEy@S zX&I>K-R!bhu3?(6bHWIg$HEl7{9g>>&l_qdd+UYb(1~BCo9LptNq&8>!yoJ3Ui(i5 zRJ|XnYBklL!{@$-7=3mJ>P@1c=7Oc79e-V7yf+%lD2!I;Y&nXBZ>=B!5?CB>LvEx6 znI%n)qqi$#X#wKB(U7XP2P=+4{b@j#r%9-K(8UqtSDk>0UKzf*HM9yqMZ1D!$2MdZ zR=`U>0zhOH1XqN?nY@AQqB7)Fp4{v&dKXvb43hZKvnN8;Po;+jY*}~*Z|W9Q0W%{D z^T}Cc<|r(Su=1K=P5>Z4 zg`et&Va}tdzBS-G-ZcO)zCWpJvGQwrHZ`@wpM420ac@bI5~KkTFfGEM3sPWO8co4^fI6lPnA)Y{ef%@{+SnoUk0+dW+*{8WvF8}}l07*qoM6N<$g7cXs A&j0`b literal 0 HcmV?d00001 diff --git a/bundles/org.simantics.logging.ui/plugin.xml b/bundles/org.simantics.logging.ui/plugin.xml new file mode 100644 index 000000000..f57c8897e --- /dev/null +++ b/bundles/org.simantics.logging.ui/plugin.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/bundles/org.simantics.logging.ui/src/org/simantics/logging/ui/Activator.java b/bundles/org.simantics.logging.ui/src/org/simantics/logging/ui/Activator.java new file mode 100644 index 000000000..942a88ba2 --- /dev/null +++ b/bundles/org.simantics.logging.ui/src/org/simantics/logging/ui/Activator.java @@ -0,0 +1,30 @@ +package org.simantics.logging.ui; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +public class Activator implements BundleActivator { + + private static BundleContext context; + + static BundleContext getContext() { + return context; + } + + /* + * (non-Javadoc) + * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext bundleContext) throws Exception { + Activator.context = bundleContext; + } + + /* + * (non-Javadoc) + * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext bundleContext) throws Exception { + Activator.context = null; + } + +} diff --git a/bundles/org.simantics.logging.ui/src/org/simantics/logging/ui/handlers/SaveLogFilesHandler.java b/bundles/org.simantics.logging.ui/src/org/simantics/logging/ui/handlers/SaveLogFilesHandler.java new file mode 100644 index 000000000..7d7983f59 --- /dev/null +++ b/bundles/org.simantics.logging.ui/src/org/simantics/logging/ui/handlers/SaveLogFilesHandler.java @@ -0,0 +1,93 @@ +package org.simantics.logging.ui.handlers; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import javax.inject.Named; + +import org.eclipse.core.runtime.Platform; +import org.eclipse.e4.core.di.annotations.Execute; +import org.eclipse.e4.ui.services.IServiceConstants; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Shell; +import org.simantics.logging.LogCollector; +import org.simantics.utils.FileUtils; +import org.simantics.utils.ui.ExceptionUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SaveLogFilesHandler { + + private static final Logger LOGGER = LoggerFactory.getLogger(SaveLogFilesHandler.class); + + private static final String[] FILTER_NAMES = { "ZIP-archive", "AllFiles (*:*)" }; + private static final String[] FILTER_EXTENSIONS = { "*.zip", "*.*" }; + private static final String USER_HOME = System.getProperty("user.home"); + + @Execute + public void execute(@Named(IServiceConstants.ACTIVE_SHELL) Shell shell) { + + FileDialog dialog = new FileDialog(shell, SWT.SAVE); + dialog.setFilterNames(FILTER_NAMES); + dialog.setFilterExtensions(FILTER_EXTENSIONS); + if (USER_HOME != null) { + if (Files.exists(Paths.get(USER_HOME))) { + dialog.setFilterPath(USER_HOME); + } + } + StringBuilder fileName = new StringBuilder(); + String productName = Platform.getProduct().getName(); + if (productName != null) + fileName.append(productName.replaceAll(" ", "_")).append("-"); + + fileName.append("logs-").append(currentLocalDateTimeStamp()); + String actualFileName = fileName.toString(); + if (LOGGER.isDebugEnabled()) + LOGGER.debug("Resolved log files name {}", actualFileName); + dialog.setFileName(actualFileName); + + String destination = dialog.open(); + if (destination != null) { + if (LOGGER.isDebugEnabled()) + LOGGER.debug("Destination for saving log files is {}", destination); + + try { + Path tempDir = Files.createTempDirectory(actualFileName); + Map> allLogs = LogCollector.allLogs(); + for (Entry> logEntry : allLogs.entrySet()) { + Path subFolder = tempDir.resolve(logEntry.getKey()); + Files.createDirectory(subFolder); + for (Path p : logEntry.getValue()) { + try { + Files.copy(p, subFolder.resolve(p.getFileName())); + } catch (IOException e) { + LOGGER.error("Could not copy {}", p.toAbsolutePath(), e); + } + } + } + FileUtils.compressZip(tempDir.toAbsolutePath().toString(), destination); + FileUtils.delete(tempDir); + } catch (Throwable t) { + LOGGER.error("Could not save log files to ZIP", t); + ExceptionUtils.logAndShowError("Could not save log files to ZIP", t); + } + } else { + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("No destination selected for saving logs"); + } + } + } + + private static String currentLocalDateTimeStamp() { + return LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd_HHmm")); + } + +} diff --git a/bundles/org.simantics.logging.ui/src/org/simantics/logging/ui/handlers/SelectLoggingLevelHandler.java b/bundles/org.simantics.logging.ui/src/org/simantics/logging/ui/handlers/SelectLoggingLevelHandler.java new file mode 100644 index 000000000..27473f182 --- /dev/null +++ b/bundles/org.simantics.logging.ui/src/org/simantics/logging/ui/handlers/SelectLoggingLevelHandler.java @@ -0,0 +1,21 @@ +package org.simantics.logging.ui.handlers; + +import javax.inject.Named; + +import org.eclipse.e4.core.di.annotations.Execute; +import org.simantics.logging.LogConfigurator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SelectLoggingLevelHandler { + + private static final Logger LOGGER = LoggerFactory.getLogger(SelectLoggingLevelHandler.class); + + @Execute + public void execute(@Named("org.simantics.logging.ui.commandparameter.selectLoggingLevel") String level) { + if (LOGGER.isDebugEnabled()) + LOGGER.debug("Setting logging level to {}", level); + LogConfigurator.setLoggingLevel(level); + } + +} diff --git a/bundles/org.simantics.logging/.classpath b/bundles/org.simantics.logging/.classpath new file mode 100644 index 000000000..eca7bdba8 --- /dev/null +++ b/bundles/org.simantics.logging/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/bundles/org.simantics.logging/.project b/bundles/org.simantics.logging/.project new file mode 100644 index 000000000..9f60062cf --- /dev/null +++ b/bundles/org.simantics.logging/.project @@ -0,0 +1,33 @@ + + + org.simantics.logging + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + org.eclipse.pde.ds.core.builder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/bundles/org.simantics.logging/.settings/org.eclipse.jdt.core.prefs b/bundles/org.simantics.logging/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..0c68a61dc --- /dev/null +++ b/bundles/org.simantics.logging/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/bundles/org.simantics.logging/META-INF/MANIFEST.MF b/bundles/org.simantics.logging/META-INF/MANIFEST.MF new file mode 100644 index 000000000..115019a65 --- /dev/null +++ b/bundles/org.simantics.logging/META-INF/MANIFEST.MF @@ -0,0 +1,16 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Simantics Logging Core +Bundle-SymbolicName: org.simantics.logging +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: org.simantics.logging.internal.Activator +Bundle-Vendor: Semantum Oy +Require-Bundle: org.eclipse.core.runtime, + org.slf4j.api, + ch.qos.logback.classic, + ch.qos.logback.core +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +Bundle-ActivationPolicy: lazy +Service-Component: logbackLogProvider.xml, + dbAndMetadataLogProvider.xml +Export-Package: org.simantics.logging diff --git a/bundles/org.simantics.logging/build.properties b/bundles/org.simantics.logging/build.properties new file mode 100644 index 000000000..c5cc5f8a3 --- /dev/null +++ b/bundles/org.simantics.logging/build.properties @@ -0,0 +1,7 @@ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + scl/,\ + logbackLogProvider.xml,\ + dbAndMetadataLogProvider.xml +source.. = src/ diff --git a/bundles/org.simantics.logging/dbAndMetadataLogProvider.xml b/bundles/org.simantics.logging/dbAndMetadataLogProvider.xml new file mode 100644 index 000000000..aa4678fe7 --- /dev/null +++ b/bundles/org.simantics.logging/dbAndMetadataLogProvider.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/bundles/org.simantics.logging/logbackLogProvider.xml b/bundles/org.simantics.logging/logbackLogProvider.xml new file mode 100644 index 000000000..9e9e6db1a --- /dev/null +++ b/bundles/org.simantics.logging/logbackLogProvider.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/bundles/org.simantics.logging/scl/LoggingUtils.scl b/bundles/org.simantics.logging/scl/LoggingUtils.scl new file mode 100644 index 000000000..500ba1b83 --- /dev/null +++ b/bundles/org.simantics.logging/scl/LoggingUtils.scl @@ -0,0 +1,9 @@ +import "Files" +import "Map" as Map + +importJava "org.simantics.logging.LogConfigurator" where + setLoggingLevel :: String -> () + setLoggingLevelForLogger :: String -> String -> () + +importJava "org.simantics.logging.LogCollector" where + allLogs :: Map.T String [Path] \ No newline at end of file diff --git a/bundles/org.simantics.logging/src/org/simantics/logging/DBAndMetadataLogProvider.java b/bundles/org.simantics.logging/src/org/simantics/logging/DBAndMetadataLogProvider.java new file mode 100644 index 000000000..79e10dbef --- /dev/null +++ b/bundles/org.simantics.logging/src/org/simantics/logging/DBAndMetadataLogProvider.java @@ -0,0 +1,60 @@ +package org.simantics.logging; + +import java.lang.reflect.Field; +import java.net.URL; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.Platform; +import org.osgi.framework.Bundle; +import org.slf4j.LoggerFactory; + +public class DBAndMetadataLogProvider implements LogProvider { + + private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(DBAndMetadataLogProvider.class); + + @Override + public List get() { + List logs = new ArrayList<>(); + Path dbClientLog = getDBClientLogLocation(); + if (dbClientLog != null) + logs.add(dbClientLog); + Path metadataLogLocation = getMetadataLogLocation(); + if (metadataLogLocation != null) + logs.add(metadataLogLocation); + return logs; + } + + private static Path getDBClientLogLocation() { + Bundle bundle = Platform.getBundle("org.simantics.db.common"); + try { + Class forName = bundle.loadClass("org.simantics.db.common.internal.config.InternalClientConfig"); + Field field = forName.getField("DB_CLIENT_LOG_FILE"); + String value = (String) field.get(null); + return Paths.get(value); + } catch (ClassNotFoundException | NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) { + LOGGER.error("Could not read db-client.log location", e); + } + return null; + } + + private static Path getMetadataLogLocation() { + String prop = System.getProperty("osgi.instance.area", null); + if (prop != null) { + try { + URL url = new URL(prop); + if ("file".equals(url .getProtocol())) { + Path path = Paths.get(url.toURI()); + return path.resolve(".metadata").resolve(".log"); + } else { + LOGGER.warn("Unsupported protocol {}", url); + } + } catch (Throwable t) { + LOGGER.error("Could not get .metadata/.log", t); + } + } + return null; + } +} diff --git a/bundles/org.simantics.logging/src/org/simantics/logging/LogCollector.java b/bundles/org.simantics.logging/src/org/simantics/logging/LogCollector.java new file mode 100644 index 000000000..4d98e2767 --- /dev/null +++ b/bundles/org.simantics.logging/src/org/simantics/logging/LogCollector.java @@ -0,0 +1,65 @@ +package org.simantics.logging; + +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceReference; +import org.simantics.logging.internal.Activator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public final class LogCollector { + + private static final Logger LOGGER = LoggerFactory.getLogger(LogCollector.class); + + public static Map> allLogs() { + Map> results = new HashMap<>(); + if (LOGGER.isDebugEnabled()) + LOGGER.debug("Collecting all logs from declarative services"); + + Collection logProviders = getLogProviders(); + for (LogProvider logProvider : logProviders) { + List logs = logProvider.get(); + String key = logProvider.getClass().getSimpleName(); + Collection existing = results.get(key); + if (existing != null) { + LOGGER.info("Duplicate log providers with name {} exist, merging logs", key); + logs.addAll(existing); + } + results.put(key, logs); + } + if (LOGGER.isDebugEnabled()) + LOGGER.debug("Found logs from {} providers", results.keySet()); + return results; + } + + private static List getLogProviders() { + ServiceReference[] serviceReferences = new ServiceReference[0]; + String key = LogProvider.class.getName(); + try { + serviceReferences = Activator.getContext().getAllServiceReferences(key, null); + } catch (InvalidSyntaxException e) { + LOGGER.error("Could not get service references for {}!", key, e); + } + if (serviceReferences.length == 0) { + if (LOGGER.isDebugEnabled()) + LOGGER.debug("No service references found for {}", key); + return Collections.emptyList(); + } + + List logProviders = new ArrayList<>(serviceReferences.length); + for (ServiceReference reference : serviceReferences) { + LogProvider logProvider = (LogProvider) Activator.getContext().getService(reference); + logProviders.add(logProvider); + } + if (LOGGER.isDebugEnabled()) + LOGGER.debug("Found {} log providers", logProviders); + return logProviders; + } +} diff --git a/bundles/org.simantics.logging/src/org/simantics/logging/LogConfigurator.java b/bundles/org.simantics.logging/src/org/simantics/logging/LogConfigurator.java new file mode 100644 index 000000000..047bac8b6 --- /dev/null +++ b/bundles/org.simantics.logging/src/org/simantics/logging/LogConfigurator.java @@ -0,0 +1,54 @@ +package org.simantics.logging; + +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.LoggerContext; + +/** + * Class for modifying the active logging configuration + * + * @author Jani Simomaa + * + */ +public final class LogConfigurator { + + private static final Logger LOGGER = LoggerFactory.getLogger(LogConfigurator.class); + + private LogConfigurator() { + } + + /** + * Sets logging level to represent the given argument + * + * @param level ERROR WARN INFO DEBUG TRACE + */ + public static void setLoggingLevel(String level) { + if (LOGGER.isInfoEnabled()) + LOGGER.info("Setting logger level to {}", level); + LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory(); + Level ll = getLoggerLevel(level); + List loggerList = context.getLoggerList(); + loggerList.forEach(l -> l.setLevel(ll)); + if (LOGGER.isDebugEnabled()) + LOGGER.debug("Loggers installed {}", loggerList); + } + + public static void setLoggingLevelForLogger(String logger, String level) { + if (LOGGER.isInfoEnabled()) + LOGGER.info("Setting logger level to {} for loggers {}", level, logger); + LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory(); + Level ll = getLoggerLevel(level); + ch.qos.logback.classic.Logger loggerList = context.getLogger(logger); + loggerList.setLevel(ll); + if (LOGGER.isDebugEnabled()) + LOGGER.debug("Loggers installed {}", loggerList); + } + + private static Level getLoggerLevel(String level) { + return Level.valueOf(level); + } +} diff --git a/bundles/org.simantics.logging/src/org/simantics/logging/LogProvider.java b/bundles/org.simantics.logging/src/org/simantics/logging/LogProvider.java new file mode 100644 index 000000000..7f7a8278c --- /dev/null +++ b/bundles/org.simantics.logging/src/org/simantics/logging/LogProvider.java @@ -0,0 +1,9 @@ +package org.simantics.logging; + +import java.nio.file.Path; +import java.util.List; +import java.util.function.Supplier; + +public interface LogProvider extends Supplier> { + +} diff --git a/bundles/org.simantics.logging/src/org/simantics/logging/LogbackLogProvider.java b/bundles/org.simantics.logging/src/org/simantics/logging/LogbackLogProvider.java new file mode 100644 index 000000000..3c88cd542 --- /dev/null +++ b/bundles/org.simantics.logging/src/org/simantics/logging/LogbackLogProvider.java @@ -0,0 +1,83 @@ +package org.simantics.logging; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.stream.Collectors; + +import org.slf4j.LoggerFactory; + +import ch.qos.logback.classic.Logger; +import ch.qos.logback.classic.LoggerContext; +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.Appender; +import ch.qos.logback.core.FileAppender; +import ch.qos.logback.core.rolling.RollingFileAppender; +import ch.qos.logback.core.spi.AppenderAttachable; + +public class LogbackLogProvider implements LogProvider { + + private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(LogbackLogProvider.class); + + @Override + public List get() { + List logs = new ArrayList<>(); + try { + LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory(); + Logger logger = context.getLogger(Logger.ROOT_LOGGER_NAME); + Iterator> appenderIter = logger.iteratorForAppenders(); + while (appenderIter.hasNext()) { + FileAppender appender = findFileAppender(appenderIter.next()); + if (appender != null) { + String logFile = ((FileAppender)appender).getFile(); + Path log = Paths.get(logFile).toAbsolutePath(); + if (appender instanceof RollingFileAppender) { + // Collect all logs + Path parent = log.getParent(); + List newLogs = Files.walk(parent).collect(Collectors.toList()); + if (LOGGER.isDebugEnabled()) + LOGGER.debug("Found {} from {}", newLogs, appender); + logs.addAll(newLogs); + } else { + logs.add(log); + } + } else { + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("Appender is not {} but is {} instead", FileAppender.class.getName(), appender != null ? appender.getClass().getName() : "null"); + } + } + } + } catch (ClassCastException e) { + // Okay, we are not using logback here + if (LOGGER.isDebugEnabled()) + LOGGER.debug("Seems like we are not using logback but {} instead", LoggerFactory.getILoggerFactory(), e); + } catch (Throwable t) { + LOGGER.error("Could not collect logs", t); + } + if (LOGGER.isDebugEnabled()) + LOGGER.debug("Found {} log files : {}", logs.size(), logs); + return logs; + } + + private static FileAppender findFileAppender(Appender appender) { + if (appender instanceof AppenderAttachable) { + // Ok, has child appender + Iterator> children = ((AppenderAttachable) appender).iteratorForAppenders(); + while (children.hasNext()) { + FileAppender app = findFileAppender(children.next()); + // TODO: returns only first FileAppender that it founds but not a collection + if (app != null) + return app; + } + return null; + } else if (appender instanceof FileAppender) { + return (FileAppender) appender; + } else { + return null; + } + } + +} diff --git a/bundles/org.simantics.logging/src/org/simantics/logging/internal/Activator.java b/bundles/org.simantics.logging/src/org/simantics/logging/internal/Activator.java new file mode 100644 index 000000000..abedac6ea --- /dev/null +++ b/bundles/org.simantics.logging/src/org/simantics/logging/internal/Activator.java @@ -0,0 +1,30 @@ +package org.simantics.logging.internal; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +public class Activator implements BundleActivator { + + private static BundleContext context; + + public static BundleContext getContext() { + return context; + } + + /* + * (non-Javadoc) + * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext bundleContext) throws Exception { + Activator.context = bundleContext; + } + + /* + * (non-Javadoc) + * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext bundleContext) throws Exception { + Activator.context = null; + } + +} diff --git a/bundles/pom.xml b/bundles/pom.xml index 7ac841ad1..6bcbd6657 100644 --- a/bundles/pom.xml +++ b/bundles/pom.xml @@ -156,6 +156,8 @@ org.simantics.layer0.utils org.simantics.layer0x.ontology org.simantics.logback.configuration + org.simantics.logging + org.simantics.logging.ui org.simantics.ltk org.simantics.ltk.antlr org.simantics.lz4 diff --git a/features/org.simantics.logging.feature/.project b/features/org.simantics.logging.feature/.project new file mode 100644 index 000000000..3ba00777a --- /dev/null +++ b/features/org.simantics.logging.feature/.project @@ -0,0 +1,17 @@ + + + org.simantics.logging.feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/features/org.simantics.logging.feature/build.properties b/features/org.simantics.logging.feature/build.properties new file mode 100644 index 000000000..64f93a9f0 --- /dev/null +++ b/features/org.simantics.logging.feature/build.properties @@ -0,0 +1 @@ +bin.includes = feature.xml diff --git a/features/org.simantics.logging.feature/feature.xml b/features/org.simantics.logging.feature/feature.xml new file mode 100644 index 000000000..3f4e57318 --- /dev/null +++ b/features/org.simantics.logging.feature/feature.xml @@ -0,0 +1,27 @@ + + + + + [Enter Feature Description here.] + + + + [Enter Copyright Description here.] + + + + [Enter License Description here.] + + + + + diff --git a/features/org.simantics.logging.ui.feature/.project b/features/org.simantics.logging.ui.feature/.project new file mode 100644 index 000000000..e4640469e --- /dev/null +++ b/features/org.simantics.logging.ui.feature/.project @@ -0,0 +1,17 @@ + + + org.simantics.logging.ui.feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/features/org.simantics.logging.ui.feature/build.properties b/features/org.simantics.logging.ui.feature/build.properties new file mode 100644 index 000000000..64f93a9f0 --- /dev/null +++ b/features/org.simantics.logging.ui.feature/build.properties @@ -0,0 +1 @@ +bin.includes = feature.xml diff --git a/features/org.simantics.logging.ui.feature/feature.xml b/features/org.simantics.logging.ui.feature/feature.xml new file mode 100644 index 000000000..6f94a0ef0 --- /dev/null +++ b/features/org.simantics.logging.ui.feature/feature.xml @@ -0,0 +1,31 @@ + + + + + [Enter Feature Description here.] + + + + [Enter Copyright Description here.] + + + + [Enter License Description here.] + + + + + + + diff --git a/features/org.simantics.sdk.feature/feature.xml b/features/org.simantics.sdk.feature/feature.xml index 0fc787e69..b7dc9adee 100644 --- a/features/org.simantics.sdk.feature/feature.xml +++ b/features/org.simantics.sdk.feature/feature.xml @@ -216,6 +216,14 @@ id="hdf.hdf5" version="0.0.0"/> + + + + org.simantics.issues.feature org.simantics.issues.ui.feature org.simantics.layer0.feature + org.simantics.logging.feature + org.simantics.logging.ui.feature org.simantics.message.feature org.simantics.migration.feature org.simantics.modeling.feature -- 2.47.1