From af6171afa608fd3ddf1bee505d72d5e599c820b2 Mon Sep 17 00:00:00 2001
From: Robert Butora <robert.butora@inaf.it>
Date: Sat, 21 Sep 2024 14:13:14 +0200
Subject: [PATCH] all: set logging levels

---
 auth/src/main/java/AuthPolicy.java            |  40 ++++++-------
 auth/src/main/java/AuthPolicyDb.java          |  29 +++++----
 auth/src/main/java/IA2TokenConvFilter.java    |  10 ++--
 auth/src/main/java/IamSigningKeyResolver.java |  12 ++--
 auth/src/main/java/IamTokenFilter.java        |  40 +++++++------
 auth/src/main/java/IntrospectResponse.java    |   4 +-
 auth/src/main/java/NeaSigningKeyResolver.java |  12 ++--
 auth/src/main/java/NeaTokenFilter.java        |  10 ++--
 auth/src/main/java/NeaTokenSettings.java      |   2 +-
 .../src/main/java/common/Subsurvey.java       |  14 ++---
 .../servlet/src/main/java/ops/CutArgs.java    |   8 +--
 .../servlet/src/main/java/ops/JdlMCutout.java |  10 ++--
 .../servlet/src/main/java/ops/Regrid.java     |  24 ++++----
 .../servlet/src/main/java/ops/Reproject.java  |   4 +-
 .../servlet/src/main/java/ops/SodaImpl.java   |  36 ++++++-----
 .../servlet/src/main/java/ops/VlkbAmqp.java   |  56 +++++++++---------
 .../servlet/src/main/java/ops/VlkbCli.java    |  42 ++++++-------
 .../src/main/java/ops/amqp/JsonDecoder.java   |   4 +-
 .../src/main/java/ops/amqp/JsonEncoder.java   |   6 +-
 .../src/main/java/ops/amqp/RpcOverAmqp.java   |  16 ++---
 .../src/main/java/ops/cli/ExecCmd.java        |  15 +++--
 .../main/java/resolver/ResolverByObsCore.java |  14 ++---
 .../java/resolver/ResolverByObsCoreDb.java    |  24 ++++----
 .../main/java/resolver/ResolverFromId.java    |  10 ++--
 .../src/main/java/webapi/AuthZFilter.java     |  12 ++--
 .../src/main/java/webapi/AuthZSettings.java   |   6 +-
 .../src/main/java/webapi/ServletCutout.java   |  50 ++++++++--------
 .../src/main/java/webapi/UWSMCutoutWork.java  |   6 +-
 .../src/main/java/webapi/UWSMergeWork.java    |   6 +-
 .../java/webapi/output/XmlSerializer.java     |   6 +-
 java-libs/lib/vlkb-volib-0.9.1-SNAPSHOT.jar   | Bin 28614 -> 28682 bytes
 31 files changed, 272 insertions(+), 256 deletions(-)

diff --git a/auth/src/main/java/AuthPolicy.java b/auth/src/main/java/AuthPolicy.java
index 8c3d60f..0471714 100644
--- a/auth/src/main/java/AuthPolicy.java
+++ b/auth/src/main/java/AuthPolicy.java
@@ -53,7 +53,7 @@ public class AuthPolicy
 
       access = Access.PUBLIC_AND_AUTHORIZED_PRIVATE;
 
-      LOGGER.info("User [Groups]: " + userName + " [ " + String.join(" ", userGroups) + " ]" );
+      LOGGER.finer("User [Groups]: " + userName + " [ " + String.join(" ", userGroups) + " ]" );
    }
 
 
@@ -67,7 +67,7 @@ public class AuthPolicy
          userName = null;
          userGroups = null;
          userGroupsValid = false;
-         LOGGER.info("Non authenticated request (UserPrincipal null in HttpServletRequest)");
+         LOGGER.finer("Non authenticated request (UserPrincipal null in HttpServletRequest)");
       }
       else
       {
@@ -81,12 +81,12 @@ public class AuthPolicy
 
             access = Access.PUBLIC_AND_AUTHORIZED_PRIVATE;
 
-            LOGGER.info("User [Groups]: " + userName + " [ " + String.join(" ", userGroups) + " ]" );
+            LOGGER.finer("User [Groups]: " + userName + " [ " + String.join(" ", userGroups) + " ]" );
          }
          else
          {
             userName = principal.getName();
-            LOGGER.info("DBG principal not instance of VlkbUser, but has user-name: " + userName);
+            LOGGER.finer("DBG principal not instance of VlkbUser, but has user-name: " + userName);
             userGroups = new String[]{""};//{"VLKB.groupA", "AllPrivate"}; // was for shiro
             userGroupsValid = true;
             access = Access.PUBLIC_AND_AUTHORIZED_PRIVATE;
@@ -163,13 +163,13 @@ public class AuthPolicy
       this.dbUserName = dbUserName;
       this.dbPassword = dbPassword;
 
-      LOGGER.info("with String[] trace");
+      LOGGER.finer("with String[] trace");
       return filterAuthorized(new ArrayList<String>(Arrays.asList(pubdidArr)), dbConnUrl);
    }
 
    private String[] filterAuthorized(ArrayList<String> pubdidList, String dbConnUrl)
    {
-      //LOGGER.info("with List <String> trace");
+      //LOGGER.fine("with List <String> trace");
       switch(access)
       {
          case PUBLIC_ONLY :
@@ -189,25 +189,25 @@ public class AuthPolicy
 
    private void filterNotPublic(ArrayList<String> pubdids, String dbConnUrl)
    {
-      LOGGER.info("trace");
+      LOGGER.fine("trace");
       assert pubdids != null;
-      //LOGGER.info("PublisherDID list original : " + String.join(" ", pubdids));
+      //LOGGER.finer("PublisherDID list original : " + String.join(" ", pubdids));
 
       List<AuthPolicyDb.PubdidGroups> privateUniqPubdids = db_queryPrivateUniqPubdidGroups(dbConnUrl, pubdids);
       List<String> notAuthorizedUniqPubdids = pubdidsNotPublic(privateUniqPubdids, userGroups);
 
-      LOGGER.info("AuthZ removes: " + String.join(" ", notAuthorizedUniqPubdids));
+      LOGGER.finest("AuthZ removes: " + String.join(" ", notAuthorizedUniqPubdids));
 
       removeNotAuthorized(pubdids, notAuthorizedUniqPubdids);
 
-      //LOGGER.info("PublisherDID list filtered : " + (pubdids.isEmpty() ? "" : String.join(" ", pubdids)));
+      //LOGGER.finest("PublisherDID list filtered : " + (pubdids.isEmpty() ? "" : String.join(" ", pubdids)));
    }
 
 
    private List<String> pubdidsNotPublic(List<AuthPolicyDb.PubdidGroups> pubdidList, String[] userGroups)
    {
-      LOGGER.info("trace");
-      //LOGGER.info("userGroups: " + String.join(" ",userGroups));
+      LOGGER.fine("trace");
+      //LOGGER.finer("userGroups: " + String.join(" ",userGroups));
 
       List<String> pubdidsNotAuthorizedList = new LinkedList<String>();
       ListIterator<AuthPolicyDb.PubdidGroups> it = pubdidList.listIterator();
@@ -216,7 +216,7 @@ public class AuthPolicy
       {
          AuthPolicyDb.PubdidGroups pubdidGroups = it.next();
 
-         //LOGGER.info(pubdidGroups.pubdid + " : " + String.join(" ",pubdidGroups.groups));
+         //LOGGER.finest(pubdidGroups.pubdid + " : " + String.join(" ",pubdidGroups.groups));
 
          if( true )// isIntersectionEmpty(pubdidGroups.groups, userGroups) )
          {
@@ -231,18 +231,18 @@ public class AuthPolicy
 
    private void filterNotAuthorized(ArrayList<String> pubdids, String dbConnUrl)
    {
-      LOGGER.info("trace");
+      LOGGER.fine("trace");
       assert pubdids != null;
-      //LOGGER.info("PublisherDID list original : " + String.join(" ", pubdids));
+      //LOGGER.finer("PublisherDID list original : " + String.join(" ", pubdids));
 
       List<AuthPolicyDb.PubdidGroups> privateUniqPubdids = db_queryPrivateUniqPubdidGroups(dbConnUrl, pubdids);
       List<String> notAuthorizedUniqPubdids = pubdidsNotAuthorized(privateUniqPubdids, userGroups);
 
-      LOGGER.info("AuthZ removes: " + String.join(" ", notAuthorizedUniqPubdids));
+      LOGGER.finest("AuthZ removes: " + String.join(" ", notAuthorizedUniqPubdids));
 
       removeNotAuthorized(pubdids, notAuthorizedUniqPubdids);
 
-      //LOGGER.info("PublisherDID list filtered : " + (pubdids.isEmpty() ? "" : String.join(" ", pubdids)));
+      //LOGGER.finest("PublisherDID list filtered : " + (pubdids.isEmpty() ? "" : String.join(" ", pubdids)));
    }
 
 
@@ -296,8 +296,8 @@ public class AuthPolicy
 
    private List<String> pubdidsNotAuthorized(List<AuthPolicyDb.PubdidGroups> pubdidList, String[] userGroups)
    {
-      LOGGER.info("trace");
-      //LOGGER.info("userGroups: " + String.join(" ",userGroups));
+      LOGGER.fine("trace");
+      //LOGGER.finer("userGroups: " + String.join(" ",userGroups));
 
       List<String> pubdidsNotAuthorizedList = new LinkedList<String>();
       ListIterator<AuthPolicyDb.PubdidGroups> it = pubdidList.listIterator();
@@ -306,7 +306,7 @@ public class AuthPolicy
       {
          AuthPolicyDb.PubdidGroups pubdidGroups = it.next();
 
-         //LOGGER.info(pubdidGroups.pubdid + " : " + String.join(" ",pubdidGroups.groups));
+         //LOGGER.finest(pubdidGroups.pubdid + " : " + String.join(" ",pubdidGroups.groups));
 
          if( isIntersectionEmpty(pubdidGroups.groups, userGroups) )
          {
diff --git a/auth/src/main/java/AuthPolicyDb.java b/auth/src/main/java/AuthPolicyDb.java
index 9f737ec..7eeb8a5 100644
--- a/auth/src/main/java/AuthPolicyDb.java
+++ b/auth/src/main/java/AuthPolicyDb.java
@@ -104,7 +104,7 @@ public class AuthPolicyDb
       //String TheQuery = "SELECT obs_publisher_did,groups FROM permissions "
       //   + "WHERE (obs_publisher_did IN (\'"+commaSepObscorePubdids+"\'));";
 
-      //LOGGER.info(TheQuery);
+      //LOGGER.finest(TheQuery);
 
       List<PubdidGroups> pubdidGroups = new LinkedList<PubdidGroups>();
       try
@@ -134,7 +134,7 @@ public class AuthPolicyDb
       }
       catch (ClassNotFoundException e)
       {
-         LOGGER.info("DB driver "+ DB_DRIVER +" not found: " + e.getMessage());
+         LOGGER.severe("DB driver "+ DB_DRIVER +" not found: " + e.getMessage());
          e.printStackTrace();
       }
       finally
@@ -148,21 +148,21 @@ public class AuthPolicyDb
 
    private void closeAll()
    {
-         if(res  != null ) try { res.close(); } catch(Exception e) {LOGGER.info("DB ResultSet::close() failed");}
-         if(st   != null ) try { st.close();  } catch(Exception e) {LOGGER.info("DB Statement::close() failed");}
-         if(conn != null ) try { conn.close();} catch(Exception e) {LOGGER.info("DB Connection::close() failed");} 
+         if(res  != null ) try { res.close(); } catch(Exception e) {LOGGER.severe("DB ResultSet::close() failed");}
+         if(st   != null ) try { st.close();  } catch(Exception e) {LOGGER.severe("DB Statement::close() failed");}
+         if(conn != null ) try { conn.close();} catch(Exception e) {LOGGER.severe("DB Connection::close() failed");} 
   }
 
    private void logSqlExInfo(SQLException se){
 
       /* dbconn.print_class_vars(); */
 
-      System.err.println("SQLState : " + se.getSQLState());
-      System.err.println("ErrorCode: " + se.getErrorCode());
-      System.err.println("Message  : " + se.getMessage());
+      LOGGER.severe("SQLState : " + se.getSQLState());
+      LOGGER.severe("ErrorCode: " + se.getErrorCode());
+      LOGGER.severe("Message  : " + se.getMessage());
       Throwable t = se.getCause();
       while(t != null) {
-         System.err.println("Cause: " + t);
+         LOGGER.severe("Cause: " + t);
          t = t.getCause();
       }
    }
@@ -184,8 +184,7 @@ public class AuthPolicyDb
          DriverManager.registerDriver(new org.postgresql.Driver());
          */
 
-      /*LOGGER.info(getClasspathString());*/
-      LOGGER.info(getRegisteredDriverList());
+      LOGGER.finest(getRegisteredDriverList());
 
       // FIXME seems DriverManager expects jdbc:postgresql driver scheme, it does not support postgresql:// scheme
       // additionally:
@@ -195,7 +194,7 @@ public class AuthPolicyDb
       // by extracting userName and password from the URL-string and prepending 'jdbc:'
       // 
 
-      /*         LOGGER.info("DBMS URL: " + dbConnUrl);
+      /*         LOGGER.finest("DBMS URL: " + dbConnUrl);
                  URI dbConnUri = new URI(dbConnUrl);
 
                  String userInfoString = dbConnUri.getUserInfo(); 
@@ -210,9 +209,9 @@ public class AuthPolicyDb
                  String password = userInfo[1];
 
                  String dbConnJdbcUrl = "jdbc:" + dbConnUrl.replace(userInfoString + "@", "");
-                 */       LOGGER.info("DBMS URL: " + dbConnUrl);
-      LOGGER.info("DBMS userName: " + dbUserName);
-      LOGGER.info("DBMS password: " + dbPassword);
+                 */       LOGGER.finest("DBMS URL: " + dbConnUrl);
+      LOGGER.finest("DBMS userName: " + dbUserName);
+      LOGGER.finest("DBMS password: " + dbPassword);
 
       conn = DriverManager.getConnection(dbConnUrl, dbUserName, dbPassword);
 
diff --git a/auth/src/main/java/IA2TokenConvFilter.java b/auth/src/main/java/IA2TokenConvFilter.java
index a64c181..b91cfac 100644
--- a/auth/src/main/java/IA2TokenConvFilter.java
+++ b/auth/src/main/java/IA2TokenConvFilter.java
@@ -21,25 +21,25 @@ import java.security.Principal;
 
 public class IA2TokenConvFilter implements Filter
 {
-  private static final Logger LOGGER = Logger.getLogger("IA2TokenConvFilter");
+  private static final Logger LOGGER = Logger.getLogger(IA2TokenConvFilter.class.getName());
 
    @Override
    public void init(FilterConfig fc) throws ServletException
    {
-      LOGGER.info("trace");
+      LOGGER.fine("trace");
    }
 
    @Override
    public void destroy()
    {
-      LOGGER.info("trace");
+      LOGGER.fine("trace");
    }
 
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
                    throws IOException, ServletException
    {
-      LOGGER.info("trace");
+      LOGGER.fine("trace");
 
         HttpServletRequest  request  = (HttpServletRequest)  req;
         HttpServletResponse response = (HttpServletResponse) res;
@@ -47,7 +47,7 @@ public class IA2TokenConvFilter implements Filter
         String authHeader = request.getHeader("Authorization");
         if (authHeader != null)
         {
-            LOGGER.info("Authorization header: " + authHeader.substring(0, 7+60) + " ...");
+            LOGGER.finer("Authorization header: " + authHeader.substring(0, 7+60) + " ...");
             if (authHeader.startsWith("Bearer "))
             {
 
diff --git a/auth/src/main/java/IamSigningKeyResolver.java b/auth/src/main/java/IamSigningKeyResolver.java
index ff89893..8c64a67 100644
--- a/auth/src/main/java/IamSigningKeyResolver.java
+++ b/auth/src/main/java/IamSigningKeyResolver.java
@@ -59,7 +59,7 @@ public class IamSigningKeyResolver extends SigningKeyResolverAdapter
    @Override
    public Key resolveSigningKey(JwsHeader jwsHeader, Claims claims)
    {
-      LOGGER.info( "IamSigningKeyResolver::resolveSigningKey" );
+      LOGGER.fine( "trace" );
 
       //inspect the header or claims, lookup and return the signing key
 
@@ -83,7 +83,7 @@ public class IamSigningKeyResolver extends SigningKeyResolverAdapter
    private Key lookupVerificationKey(String keyId)
          throws Exception, GeneralSecurityException
       {
-         LOGGER.info( "IamSigningKeyResolver::lookupVerificationKey" );
+         LOGGER.fine( "trace" );
 
          String jsonKeys = doHttps();
 
@@ -95,7 +95,7 @@ public class IamSigningKeyResolver extends SigningKeyResolverAdapter
 
    private String doHttps() throws Exception
    {
-      LOGGER.info("doHttps : " + keysURL);
+      LOGGER.fine("trace keysURL : " + keysURL);
 
       URL myUrl = new URL(keysURL);
       HttpsURLConnection conn = (HttpsURLConnection)myUrl.openConnection();
@@ -118,7 +118,7 @@ public class IamSigningKeyResolver extends SigningKeyResolverAdapter
    private Key getKeyFromKeys(String jsonKeys, String keyId)
          throws JsonProcessingException, GeneralSecurityException, IOException
       {
-         LOGGER.info( "IamSigningKeyResolver::getKeyFromKeys");
+         LOGGER.fine( "trace" );
 
          Key key = null;
 
@@ -131,13 +131,13 @@ public class IamSigningKeyResolver extends SigningKeyResolverAdapter
             {
                String nodeContent = mapper.writeValueAsString(node);
 
-               LOGGER.info("key: " + nodeContent);
+               LOGGER.finest("key: " + nodeContent);
 
                Jwk<?> jwk = Jwks.parser().build().parse(nodeContent);
 
                String jwkkid = jwk.getId();
 
-               LOGGER.info("kid-token : " + keyId + "kid-store : " + jwkkid + " key-type: " + jwk.getType());
+               LOGGER.finest("kid-token : " + keyId + "kid-store : " + jwkkid + " key-type: " + jwk.getType());
 
                if(keyId.equals(jwkkid))
                {
diff --git a/auth/src/main/java/IamTokenFilter.java b/auth/src/main/java/IamTokenFilter.java
index f434f82..b4f255f 100644
--- a/auth/src/main/java/IamTokenFilter.java
+++ b/auth/src/main/java/IamTokenFilter.java
@@ -35,7 +35,7 @@ import javax.servlet.ServletOutputStream;
 
 public class IamTokenFilter implements Filter
 {
-   private static final Logger LOGGER = Logger.getLogger("IamTokenFilter");
+   private static final Logger LOGGER = Logger.getLogger(IamTokenFilter.class.getName());
    private static final IamTokenSettings settings = IamTokenSettings.getInstance();
 
    final String RESPONSE_ENCODING = "utf-8";
@@ -64,7 +64,7 @@ public class IamTokenFilter implements Filter
       if(authHeader==null)
       {
          final String AUTH_ERR = "Request without Authorization header. Only authenticated requests allowed.";
-         LOGGER.info(AUTH_ERR);
+         LOGGER.warning(AUTH_ERR);
          sendAuthenticationError((HttpServletResponse)resp, writer, AUTH_ERR);
       }
       else
@@ -73,7 +73,7 @@ public class IamTokenFilter implements Filter
 
          if (authHeader.startsWith("Bearer ") && (authHeader.length() > "Bearer ".length()))
          {
-            LOGGER.info("Request with Authorization header and has Bearer entry");
+            LOGGER.warning("Request with Authorization header and has Bearer entry");
             String token = authHeader.substring("Bearer ".length()).trim();
 
             doFilterBearer(req, token, resp, chain);
@@ -82,7 +82,7 @@ public class IamTokenFilter implements Filter
          {
             final String AUTH_ERR = "Authorization header with Bearer-token expected, but it starts with : "
                + authHeader.substring(0, "Bearer ".length()) + "...";
-            LOGGER.info(AUTH_ERR);
+            LOGGER.warning(AUTH_ERR);
             sendUsageError((HttpServletResponse)resp, writer, AUTH_ERR);
          }
       }
@@ -94,6 +94,8 @@ public class IamTokenFilter implements Filter
    private void doFilterBearer(ServletRequest req, String token, ServletResponse resp, FilterChain chain)
          throws IOException, ServletException
       {
+         LOGGER.fine("trace");
+
          HttpServletRequest  request  = (HttpServletRequest) req;
          HttpServletResponse response = (HttpServletResponse)resp;
 
@@ -112,42 +114,42 @@ public class IamTokenFilter implements Filter
                String ivoidPath = ivoid.getLocalPart();
                String tokenPath = insResp.getPathFromStorageReadScope();
 
-               LOGGER.info("Path from IVOID: " + ivoidPath);
-               LOGGER.info("Path from token: " + tokenPath);
+               LOGGER.finest("Path from IVOID: " + ivoidPath);
+               LOGGER.finest("Path from token: " + tokenPath);
 
                if(tokenPath.endsWith(ivoidPath))
                {
-                  LOGGER.info("Access authorized.");
+                  LOGGER.finest("Access authorized.");
                   chain.doFilter(request, response);
                }
                else
                {
                   final String AUTH_ERR = "Bearer token does not authorize access to : " + ivoidPath;
-                  LOGGER.info(AUTH_ERR);
+                  LOGGER.finer(AUTH_ERR);
                   sendAuthorizationError(response, writer, AUTH_ERR);
                }
             }
             else
             {
                final String AUTH_ERR = "Bearer-token is inactive.";
-               LOGGER.info(AUTH_ERR);
+               LOGGER.finer(AUTH_ERR);
                sendAuthorizationError(response, writer, AUTH_ERR);
             }
 
          }
          catch(IndexOutOfBoundsException ex)
          {
-            LOGGER.info("IndexOutOfBoundsException: " + ex.getMessage());
+            LOGGER.warning("IndexOutOfBoundsException: " + ex.getMessage());
             sendUsageError(response, writer, ex.getMessage());
          }
          catch(IllegalArgumentException ex)
          {
-            LOGGER.info("IllegalArgumentException: " + ex.getMessage());
+            LOGGER.warning("IllegalArgumentException: " + ex.getMessage());
             sendUsageError(response, writer, ex.getMessage());
          }
          catch(Exception ex)
          {
-            LOGGER.info("Exception: " + ex.getMessage());
+            LOGGER.severe("Exception: " + ex.getMessage());
             ex.printStackTrace();
             sendError(response, writer, ex.toString());
          }
@@ -240,9 +242,9 @@ public class IamTokenFilter implements Filter
 
      String  qString = request.getQueryString();
      if(qString == null)
-     LOGGER.info(request.getRequestURL().toString());
+     LOGGER.finest(request.getRequestURL().toString());
      else
-     LOGGER.info(request.getRequestURL() + "    " + qString);
+     LOGGER.finest(request.getRequestURL() + "    " + qString);
 
      String authHeader = request.getHeader("Authorization");
      if (authHeader == null)
@@ -255,7 +257,7 @@ public class IamTokenFilter implements Filter
      }
      else
      {
-     LOGGER.info("Request without Authorization header, no Principal added");
+     LOGGER.finest("Request without Authorization header, no Principal added");
      response.sendError(HttpServletResponse.SC_BAD_REQUEST,
      "No Authorization in HTTP-header. Only authorized requests allowed.");
      }
@@ -266,7 +268,7 @@ public class IamTokenFilter implements Filter
 
      if (authHeader.startsWith("Bearer ") && (authHeader.length() > "Bearer ".length()))
      {
-     LOGGER.info("Request with Authorization header and has Bearer entry");
+     LOGGER.finest("Request with Authorization header and has Bearer entry");
 
      String jws = authHeader.substring("Bearer ".length());
 
@@ -345,7 +347,7 @@ public class IamTokenFilter implements Filter
 
    Claims claims = jws.getBody();
 
-   LOGGER.info("scope: " + (String)claims.get("scope"));
+   LOGGER.finest("scope: " + (String)claims.get("scope"));
 
    List<String> scopes = parseScopes(claims);
 
@@ -359,11 +361,11 @@ public class IamTokenFilter implements Filter
    }
    }
 
-   LOGGER.info("storage.read: " + storageReadScope);
+   LOGGER.finest("storage.read: " + storageReadScope);
 
    String path = storageReadScope.substring(storageReadScope.lastIndexOf(":") + 1);
 
-   LOGGER.info("path: " + path);
+   LOGGER.finest("path: " + path);
 
    // set User/Principal
 
diff --git a/auth/src/main/java/IntrospectResponse.java b/auth/src/main/java/IntrospectResponse.java
index 4ac4b8b..e7c0f4e 100644
--- a/auth/src/main/java/IntrospectResponse.java
+++ b/auth/src/main/java/IntrospectResponse.java
@@ -20,7 +20,7 @@ import com.fasterxml.jackson.annotation.JsonAutoDetect;
 
 class IntrospectResponse
 {
-   private static final Logger LOGGER = Logger.getLogger("IntrospectResponse");
+   private static final Logger LOGGER = Logger.getLogger(IntrospectResponse.class.getName());
 
    public boolean active;
    public String  scope;
@@ -59,7 +59,7 @@ class IntrospectResponse
 
    private String doHttps(String uPass, String url, String postParams) throws Exception
    {
-      LOGGER.info("doHttps : " + url);
+      LOGGER.fine("url : " + url);
 
       URL myUrl = new URL(url);
       HttpsURLConnection conn = (HttpsURLConnection)myUrl.openConnection();
diff --git a/auth/src/main/java/NeaSigningKeyResolver.java b/auth/src/main/java/NeaSigningKeyResolver.java
index 72af234..4ec28dc 100644
--- a/auth/src/main/java/NeaSigningKeyResolver.java
+++ b/auth/src/main/java/NeaSigningKeyResolver.java
@@ -63,7 +63,7 @@ public class NeaSigningKeyResolver extends SigningKeyResolverAdapter
 
    private String doHttps() throws Exception
    {
-      LOGGER.info("doHttps : " + keysURL);
+      LOGGER.fine("keysURL : " + keysURL);
 
       URL myUrl = new URL(keysURL);
       HttpsURLConnection conn = (HttpsURLConnection)myUrl.openConnection();
@@ -105,7 +105,7 @@ public class NeaSigningKeyResolver extends SigningKeyResolverAdapter
    private String getCertFromKeys(String jsonKeys, String keyId)
          throws JsonProcessingException, GeneralSecurityException, IOException
       {
-         LOGGER.info( "NeaSigningKeyResolver::getCertFromKeys");
+         LOGGER.fine( "trace");
 
          ObjectMapper mapper = new ObjectMapper();
 
@@ -119,7 +119,7 @@ public class NeaSigningKeyResolver extends SigningKeyResolverAdapter
                String nodeContent = mapper.writeValueAsString(node);
                NeaKey key = mapper.readValue(nodeContent,NeaKey.class);
 
-               LOGGER.info("keyId    : " + keyId
+               LOGGER.finest("keyId    : " + keyId
                      +"\nKey::kid : " + key.kid);
 
                if(keyId.equals(key.kid))
@@ -138,7 +138,7 @@ public class NeaSigningKeyResolver extends SigningKeyResolverAdapter
    private PublicKey getPublicKeyFromPemCert(String certBase64)
          throws GeneralSecurityException
       {
-         LOGGER.info( "NeaSigningKeyResolver::getPublicKeyFromPemCert");
+         LOGGER.fine( "trace" );
 
          CertificateFactory fac = CertificateFactory.getInstance("X509");
          ByteArrayInputStream in = new ByteArrayInputStream(Base64.getDecoder().decode(certBase64));
@@ -152,7 +152,7 @@ public class NeaSigningKeyResolver extends SigningKeyResolverAdapter
    private Key lookupVerificationKey(String keyId)
          throws Exception, GeneralSecurityException
       {
-         LOGGER.info( "NeaSigningKeyResolver::lookupVerificationKey" );
+         LOGGER.fine( "trace" );
 
          String jsonKeys = doHttps();
 
@@ -169,7 +169,7 @@ public class NeaSigningKeyResolver extends SigningKeyResolverAdapter
    @Override
    public Key resolveSigningKey(JwsHeader jwsHeader, Claims claims)
    {
-      LOGGER.info( "NeaSigningKeyResolver::resolveSigningKey" );
+      LOGGER.fine( "trace" );
 
       //inspect the header or claims, lookup and return the signing key
 
diff --git a/auth/src/main/java/NeaTokenFilter.java b/auth/src/main/java/NeaTokenFilter.java
index f24dc4c..cbb5fc2 100644
--- a/auth/src/main/java/NeaTokenFilter.java
+++ b/auth/src/main/java/NeaTokenFilter.java
@@ -34,7 +34,7 @@ import javax.servlet.http.HttpServletResponse;
 
 public class NeaTokenFilter implements Filter
 {
-   private static final Logger LOGGER = Logger.getLogger("NeaTokenFilter");
+   private static final Logger LOGGER = Logger.getLogger(NeaTokenFilter.class.getName());
    private static final NeaTokenSettings settings = NeaTokenSettings.getInstance();
 
    final String resourceId = settings.security.resourceId; //"vlkb"
@@ -57,9 +57,9 @@ public class NeaTokenFilter implements Filter
 
    String  qString = request.getQueryString();
    if(qString == null)
-      LOGGER.info(request.getRequestURL().toString());
+      LOGGER.finest(request.getRequestURL().toString());
    else
-      LOGGER.info(request.getRequestURL() + "    " + qString);
+      LOGGER.finest(request.getRequestURL() + "    " + qString);
 
    String authHeader = request.getHeader("Authorization");
    if (authHeader == null)
@@ -72,7 +72,7 @@ public class NeaTokenFilter implements Filter
       }
       else
       {
-         LOGGER.info("Request without Authorization header, no Principal added");
+         LOGGER.warning("Request without Authorization header, no Principal added");
          response.sendError(HttpServletResponse.SC_BAD_REQUEST,
                "No Authorization in HTTP-header. Only authorized requests allowed.");
       }
@@ -83,7 +83,7 @@ public class NeaTokenFilter implements Filter
 
       if (authHeader.startsWith("Bearer ") && (authHeader.length() > "Bearer ".length()))
       {
-         LOGGER.info("Request with Authorization header and has Bearer entry");
+         LOGGER.finer("Request with Authorization header and has Bearer entry");
 
          String jws = authHeader.substring("Bearer ".length());
 
diff --git a/auth/src/main/java/NeaTokenSettings.java b/auth/src/main/java/NeaTokenSettings.java
index ce71c44..766d390 100644
--- a/auth/src/main/java/NeaTokenSettings.java
+++ b/auth/src/main/java/NeaTokenSettings.java
@@ -20,7 +20,7 @@ import java.util.ArrayList;
 
 class NeaTokenSettings
 {
-   private static final Logger LOGGER = Logger.getLogger("NeaTokenSettings");
+   //private static final Logger LOGGER = Logger.getLogger(NeaTokenSettings.class.getName());
 
    static final String VLKB_PROPERTIES = "neatoken.properties";
 
diff --git a/data-access/servlet/src/main/java/common/Subsurvey.java b/data-access/servlet/src/main/java/common/Subsurvey.java
index d5dfe48..d8f64cf 100644
--- a/data-access/servlet/src/main/java/common/Subsurvey.java
+++ b/data-access/servlet/src/main/java/common/Subsurvey.java
@@ -15,7 +15,7 @@ import java.util.ArrayList;
 
 class Subsurvey
 {
-   private static final Logger LOGGER = Logger.getLogger("Subsurvey");
+   private static final Logger LOGGER = Logger.getLogger(Subsurvey.class.getName());
 
    String description;
    String surveyname;
@@ -62,7 +62,7 @@ class Subsurvey
 
    static public Subsurvey findSubsurveyByStoragePath(Subsurvey[] dbSubsurveys, String storagePath)
    {
-      LOGGER.info("trace storagePath: " + storagePath);
+      LOGGER.fine("trace storagePath: " + storagePath);
 
       for(Subsurvey curr : dbSubsurveys)
       {
@@ -109,15 +109,15 @@ class Subsurvey
 
    public static Subsurvey[] loadSubsurveys(String csvFilename)
    {
-      LOGGER.info("trace");
+      LOGGER.fine("trace");
 
       /* avoid access files-system if csv-filename not configured */
       if( (csvFilename == null) || ( (csvFilename != null) && (csvFilename.length() < 1) ) )
       {
-         LOGGER.warning("csvFilename is empty, metadata not loaded");
+         LOGGER.config("csvFilename is empty, metadata not loaded");
          return null;
       }
-      LOGGER.info("load from: " + csvFilename);
+      LOGGER.config("load from: " + csvFilename);
 
       try
       {
@@ -147,13 +147,13 @@ class Subsurvey
       }
       catch(IOException ex) 
       {
-         LOGGER.info("Error while loading " + csvFilename + " -> " + ex.getMessage());
+         LOGGER.warning("While loading " + csvFilename + " -> " + ex.getMessage());
          return null;
          //throw new IllegalStateException("Error while loading " + csvFilename + " file", ex);
       }
       catch(CsvValidationException ex) 
       {
-         LOGGER.info("Error while reading " + csvFilename + " -> " + ex.getMessage());
+         LOGGER.warning("While reading " + csvFilename + " -> " + ex.getMessage());
          return null;
          //throw new IllegalStateException("Error while reading " + csvFilename + " file", ex);
       }
diff --git a/data-access/servlet/src/main/java/ops/CutArgs.java b/data-access/servlet/src/main/java/ops/CutArgs.java
index 2203c9c..d677c14 100644
--- a/data-access/servlet/src/main/java/ops/CutArgs.java
+++ b/data-access/servlet/src/main/java/ops/CutArgs.java
@@ -53,11 +53,11 @@ import vo.parameter.*;
 // FIXME or clla this Jdl.java ?
 class CutArgs
 {
-   static final Logger LOGGER = Logger.getLogger("CutArgs");
+   static final Logger LOGGER = Logger.getLogger(CutArgs.class.getName());
 
    static CutArgs[] parseCutArgsArr(String jsonString)
    {
-      LOGGER.info("trace : " + jsonString);
+      LOGGER.fine("trace : " + jsonString);
 
       List<CutArgs> argsList = new ArrayList<CutArgs>();
 
@@ -71,7 +71,7 @@ class CutArgs
          {
             // FIXME check type
             JSONObject jElem = (JSONObject) o;
-            LOGGER.info("jElem: " + jElem.toString());
+            LOGGER.finest("jElem: " + jElem.toString());
 
             CutArgs args = new CutArgs();
 
@@ -102,7 +102,7 @@ class CutArgs
             if(jCoord != null)
             {
                // legacy
-               LOGGER.info("TEST: " + jCoord.toString());
+               LOGGER.finest("TEST: " + jCoord.toString());
 
                args.lon = (Double) jCoord.get("l");
                args.lat = (Double) jCoord.get("b");
diff --git a/data-access/servlet/src/main/java/ops/JdlMCutout.java b/data-access/servlet/src/main/java/ops/JdlMCutout.java
index 4b24b11..a8f10b7 100644
--- a/data-access/servlet/src/main/java/ops/JdlMCutout.java
+++ b/data-access/servlet/src/main/java/ops/JdlMCutout.java
@@ -12,7 +12,7 @@ import org.json.simple.parser.ParseException;
 
 public class JdlMCutout
 {
-   static final Logger LOGGER = Logger.getLogger("JdlMCutout");
+   static final Logger LOGGER = Logger.getLogger(JdlMCutout.class.getName());
 
 
    /* used in mcutout to resolve pubdids to pathanme+hdunum */
@@ -137,9 +137,9 @@ public class JdlMCutout
 
             JSONArray jsonArray = (JSONArray)jsonObject.get("responses");
 
-            LOGGER.info("jsonArray.size  [responses]: " + jsonArray.size());
+            LOGGER.finest("jsonArray.size  [responses]: " + jsonArray.size());
             //MCutResult.Cut[] cutResArr = new MCutResult.Cut[jsonArray.size()];
-            //LOGGER.info("cutResArr.length[responses]: " + cutResArr.length);
+            //LOGGER.finest("cutResArr.length[responses]: " + cutResArr.length);
 
             ArrayList<MCutResult.Cut> cutResList = new ArrayList<MCutResult.Cut>();
 
@@ -148,7 +148,7 @@ public class JdlMCutout
             Iterator<JSONObject> itr = jsonArray.iterator();
             while (itr.hasNext())
             {
-               LOGGER.info("i: " + String.valueOf(i));
+               LOGGER.finest("i: " + String.valueOf(i));
                JSONObject jObj = itr.next();
 
                MCutResult mc = new MCutResult();
@@ -172,7 +172,7 @@ public class JdlMCutout
             cuts.fileSize = fileSize;
             cuts.fileName = fileName;
             cuts.cutResArr = cutResList.toArray(new MCutResult.Cut[0]);//cutResArr;
-            LOGGER.info("cuts.cutResArr.length[responses]: " + cuts.cutResArr.length);
+            LOGGER.finest("cuts.cutResArr.length[responses]: " + cuts.cutResArr.length);
          }
       }
       catch  (ParseException e)
diff --git a/data-access/servlet/src/main/java/ops/Regrid.java b/data-access/servlet/src/main/java/ops/Regrid.java
index 148c377..04ef066 100644
--- a/data-access/servlet/src/main/java/ops/Regrid.java
+++ b/data-access/servlet/src/main/java/ops/Regrid.java
@@ -4,7 +4,7 @@
 // - merge : high level, which uses mergefiles after cutout
 
 import java.util.logging.Logger;
-import java.util.logging.Level;
+//import java.util.logging.Level;
 
 import java.io.IOException;
 import java.util.*; // ArrayList<String>
@@ -64,9 +64,9 @@ class Regrid
             Vnaxis.add(nx);
 
          } catch (FitsException e) {
-            LOGGER.log(Level.SEVERE, "dimensions:",e);
+            LOGGER.severe("dimensions: " + e.getMessage());
          } catch (IOException e) {
-            LOGGER.log(Level.SEVERE, "dimensions:",e);
+            LOGGER.severe("dimensions:" + e.getMessage());
          }
       }
       // check that dimensions in all files match
@@ -126,7 +126,7 @@ class Regrid
             // get card values as string (for exact match comparison to avoid string -> double conversion artifacts)
             // String allcardstr   = f.getHDU(0).getHeader().findKey("CRVAL3");
             // String cardvaluestr = f.getHDU(0).getHeader().findCard("CRVAL3").getValue();
-            // LOGGER.info("CRVAL3 as string: " + cardvaluestr);
+            // LOGGER.finest("CRVAL3 as string: " + cardvaluestr);
 
             Vcrval.add(f.getHDU(0).getHeader().getDoubleValue("CRVAL3"));
             Vcrpix.add(f.getHDU(0).getHeader().getDoubleValue("CRPIX3"));
@@ -135,16 +135,16 @@ class Regrid
 
 
          } catch (FitsException e) {
-            LOGGER.log(Level.SEVERE, "regrid_vel2:",e);
+            LOGGER.severe("regrid_vel2: " + e.getMessage());
          } catch (IOException e) {
-            LOGGER.log(Level.SEVERE, "regrid_vel2:",e);
+            LOGGER.severe("regrid_vel2: " + e.getMessage());
          }
 
       }
       /*/ debug print
         for( int ix = 0; ix < Vcrval.size() ; ix++ ) {
 
-        LOGGER.info(ix +
+        LOGGER.finest(ix +
         " " + Vcrval.get(ix) +
         " " + Vcdelt.get(ix) +
         " " + Vcrpix.get(ix) +
@@ -161,7 +161,7 @@ class Regrid
       // max diff(CRVAL3) << absvalue(CDELT3)
       //
       long dnaxis = Collections.max(Vnaxis) - Collections.min(Vnaxis);
-      //LOGGER.info("dNAXIS : " + dnaxis);
+      //LOGGER.finest("dNAXIS : " + dnaxis);
       if( dnaxis != 0 ) {
          return false;
       }
@@ -173,12 +173,12 @@ class Regrid
 
       // FIXME use exceptions instead...
       if(absavgCDELT == 0.0) {
-         LOGGER.warning("regrid: avg(CDELT3) == 0");
+         LOGGER.finest("regrid: avg(CDELT3) == 0");
          return false;
       }
 
       double dcdelt = java.lang.Math.abs(maxCDELT - minCDELT);
-      //LOGGER.info("dCDELT : " + dcdelt
+      //LOGGER.finest("dCDELT : " + dcdelt
       //                   + " ratio: " +
       //                   String.format("%.1f",100.0*dcdelt/absavgCDELT)
       //                   + " %" );
@@ -189,7 +189,7 @@ class Regrid
       double minCRVAL = Collections.min(Vcrval);
       double maxCRVAL = Collections.max(Vcrval);
       double dcrval = java.lang.Math.abs(maxCRVAL - minCRVAL);
-      //LOGGER.info("dCRVAL : " + dcrval + "|CDELT| : " + absavgCDELT
+      //LOGGER.finest("dCRVAL : " + dcrval + "|CDELT| : " + absavgCDELT
       //                   + " ratio: " +
       //                   String.format("%.1f",100.0*dcrval/absavgCDELT)
       //                   + " %" );
@@ -242,7 +242,7 @@ class Regrid
 
          } catch(Exception e) {
             // FIXME do error handling properly...
-            LOGGER.log(Level.SEVERE, "regrid_vel2:", e);
+            LOGGER.severe("regrid_vel2: " + e.getMessage());
          }
 
       }
diff --git a/data-access/servlet/src/main/java/ops/Reproject.java b/data-access/servlet/src/main/java/ops/Reproject.java
index 4245798..0e1cb00 100644
--- a/data-access/servlet/src/main/java/ops/Reproject.java
+++ b/data-access/servlet/src/main/java/ops/Reproject.java
@@ -23,9 +23,9 @@ class Reproject implements Runnable
    public void run()
    {
       String name = Thread.currentThread().getName();
-      VlkbAmqp.LOGGER.info("Start of " + name);
+      VlkbAmqp.LOGGER.fine("Start of " + name);
       response = datasets.mergefiles_reproject(id, prefix, fileName);
-      VlkbAmqp.LOGGER.info("End   of " + name);
+      VlkbAmqp.LOGGER.fine("End   of " + name);
    }
 
 }
diff --git a/data-access/servlet/src/main/java/ops/SodaImpl.java b/data-access/servlet/src/main/java/ops/SodaImpl.java
index 637c283..4c69b40 100644
--- a/data-access/servlet/src/main/java/ops/SodaImpl.java
+++ b/data-access/servlet/src/main/java/ops/SodaImpl.java
@@ -30,7 +30,7 @@ import vo.parameter.*;
 
 class SodaImpl implements Soda
 {
-   private static final Logger LOGGER = Logger.getLogger("SodaImpl");
+   private static final Logger LOGGER = Logger.getLogger(SodaImpl.class.getName());
    private static Settings.FITSPaths fitsPaths = null;
 
    private SodaImpl() {}
@@ -38,7 +38,7 @@ class SodaImpl implements Soda
 
    public SodaImpl(Settings.FITSPaths fitsPaths)
    {
-      LOGGER.info("trace");
+      LOGGER.fine("trace");
       this.fitsPaths = fitsPaths;
    }
 
@@ -47,6 +47,8 @@ class SodaImpl implements Soda
          Pos pos, Band band, Time time, Pol pol, String pixels,
          OutputStream outputStream)  throws IOException, InterruptedException
    {
+      LOGGER.fine("trace");
+
       Instant start = Instant.now();
 
       boolean has_overlap  = false;
@@ -67,7 +69,7 @@ class SodaImpl implements Soda
          jReq.add(time);
          jReq.add(pol);
          String coordString = jReq.toString();
-         LOGGER.info("coordString: " + coordString);
+         LOGGER.finest("coordString: " + coordString);
 
          /* calc bounds */
 
@@ -79,7 +81,7 @@ class SodaImpl implements Soda
 
          ExecCmd execBounds = new ExecCmd();
          execBounds.doRun(bos, cmdBounds);
-         LOGGER.info("execBounds exitValue: " + execBounds.exitValue);
+         LOGGER.finest("execBounds exitValue: " + execBounds.exitValue);
 
          boolean has_result = (execBounds.exitValue == 0);
 
@@ -88,7 +90,7 @@ class SodaImpl implements Soda
             boundsString = new String(bos.toByteArray());
 
             boundsString = replaceWithGrid(boundsString, pos, band, time, pol);
-            LOGGER.info("boundsString(with GRID): " + boundsString);
+            LOGGER.finest("boundsString(with GRID): " + boundsString);
 
             has_overlap = !((boundsString != null) && boundsString.trim().isEmpty());
 
@@ -101,7 +103,7 @@ class SodaImpl implements Soda
          bos.close();
 
          Instant boundsDone = Instant.now();
-         LOGGER.info("EXECTIME boundsDone: " + Duration.between(start, boundsDone));
+         LOGGER.finer("EXECTIME boundsDone: " + Duration.between(start, boundsDone));
       }
 
       if(has_overlap || pixels_valid)
@@ -119,12 +121,12 @@ class SodaImpl implements Soda
          cmdCut[5] = fitsPaths.cutouts();
 
          if(outputStream == null)
-            LOGGER.info("supplied outputStream for cut-file is null");
+            LOGGER.finest("supplied outputStream for cut-file is null");
 
          ExecCmd execCut = new ExecCmd();
          execCut.doRun(outputStream, cmdCut);
 
-         LOGGER.info("execCut exitValue: " + execCut.exitValue);
+         LOGGER.finest("execCut exitValue: " + execCut.exitValue);
 
          boolean cut_successful = (execCut.exitValue == 0);
 
@@ -134,7 +136,7 @@ class SodaImpl implements Soda
          }
 
          Instant cutDone = Instant.now();
-         LOGGER.info("EXECTIME    cutDone: " + Duration.between(start, cutDone));
+         LOGGER.finer("EXECTIME    cutDone: " + Duration.between(start, cutDone));
       }
       else
       {
@@ -146,6 +148,8 @@ class SodaImpl implements Soda
 
    private String genRegionForVlkbOverlapCmd(Pos pos, Band band)
    {
+      LOGGER.fine("trace");
+
       String region = "";
 
       if(pos != null)
@@ -171,7 +175,7 @@ class SodaImpl implements Soda
          }
          else 
          {
-            LOGGER.info("FIXME here Exception: POLYGON not supported or pos.shape invalid: " + pos.shape);
+            LOGGER.finest("FIXME here Exception: POLYGON not supported or pos.shape invalid: " + pos.shape);
          }
 
       }
@@ -194,12 +198,12 @@ class SodaImpl implements Soda
       // remove end-of-line (was added by vlkb_ast.cpp: cout << ... << endl)
       String lineSeparator = System.lineSeparator();
       wcsBounds = wcsBounds.replace(lineSeparator, "");
-      LOGGER.info("BOUNDS: " + wcsBounds);
+      LOGGER.finest("BOUNDS: " + wcsBounds);
 
       // replace in wcsBounds those bounds where pos,band,time or pol has system=GRID
 
       String[] substr = wcsBounds.split("(?=AXES)", 2);
-      for(String ss : substr) LOGGER.info("boundsResult: " + ss);
+      for(String ss : substr) LOGGER.finest("boundsResult: " + ss);
 
       String boundsString = substr[0];
       boolean noOverlap = ((boundsString != null) && boundsString.trim().isEmpty());
@@ -213,12 +217,12 @@ class SodaImpl implements Soda
          if(substr.length > 1)
          {
             axesTypes = substr[1].replace("AXES"," ").trim();
-            LOGGER.info("AXES TYPES: " + axesTypes);
+            LOGGER.finest("AXES TYPES: " + axesTypes);
 
             String[] bnds  = normalize(boundsString);
             String[] types = normalize(axesTypes);
             // assert: bnds.length == types.length
-            LOGGER.info("boundsCount: " + bnds.length  + " typesCount: " + types.length);
+            LOGGER.finest("boundsCount: " + bnds.length  + " typesCount: " + types.length);
 
             if(bnds.length == types.length)
                boundsString = replaceBounds(bnds, types, pos, band);
@@ -246,7 +250,7 @@ class SodaImpl implements Soda
          }
       }
 
-      LOGGER.info("replaced: " + String.join(" ", bnds)) ;
+      LOGGER.finest("replaced: " + String.join(" ", bnds)) ;
 
       return "[" + String.join(" ", bnds)  + "]";
    }
@@ -256,7 +260,7 @@ class SodaImpl implements Soda
    private String[] normalize(String spaceStr)
    {
       String other = spaceStr.replace("[","").replace("]","");
-      LOGGER.info("normalize: " + other);
+      LOGGER.finest("normalize: " + other);
       return other.split("\\s+");
    }
 
diff --git a/data-access/servlet/src/main/java/ops/VlkbAmqp.java b/data-access/servlet/src/main/java/ops/VlkbAmqp.java
index 64af5a4..0184865 100644
--- a/data-access/servlet/src/main/java/ops/VlkbAmqp.java
+++ b/data-access/servlet/src/main/java/ops/VlkbAmqp.java
@@ -29,7 +29,7 @@ import vo.parameter.*;
 
 class VlkbAmqp implements Vlkb
 {
-   static final Logger LOGGER = Logger.getLogger("VlkbAmqp");
+   static final Logger LOGGER = Logger.getLogger(VlkbAmqp.class.getName());
 
    private Settings    settings   = null;
    private Subsurvey[] subsurveys = null;
@@ -37,7 +37,7 @@ class VlkbAmqp implements Vlkb
 
    public VlkbAmqp()
    {
-      LOGGER.info("trace VlkbAmqp()");
+      LOGGER.fine("trace VlkbAmqp()");
       this.settings = Settings.getInstance();
       this.resolver = (settings.dbConn.isDbUriEmpty() ? new ResolverFromId(subsurveys)
             : new ResolverByObsCore(settings.dbConn, subsurveys));
@@ -46,7 +46,7 @@ class VlkbAmqp implements Vlkb
 
    public VlkbAmqp(Settings settings)
    {
-      LOGGER.info("trace VlkbAmqp(settings)");
+      LOGGER.fine("trace VlkbAmqp(settings)");
       this.settings = settings;
       this.resolver = (settings.dbConn.isDbUriEmpty() ? new ResolverFromId(subsurveys)
             : new ResolverByObsCore(settings.dbConn, subsurveys));
@@ -56,7 +56,7 @@ class VlkbAmqp implements Vlkb
 
    public VlkbAmqp(Settings settings, Subsurvey[] subsurveys)
    {
-      LOGGER.info("trace VlkbAmqp(settings, subsurveys)");
+      LOGGER.fine("trace VlkbAmqp(settings, subsurveys)");
       this.settings = settings;
       this.subsurveys = subsurveys;
       this.resolver = (settings.dbConn.isDbUriEmpty() ? new ResolverFromId(subsurveys)
@@ -69,7 +69,7 @@ class VlkbAmqp implements Vlkb
    public CutResult doMerge(String[] idArr, Coord coord, boolean countNullValues)
       throws FileNotFoundException, IOException
    {
-      LOGGER.info("trace");
+      LOGGER.fine("trace");
 
       return merge(idArr, coord, countNullValues);
    }
@@ -82,11 +82,11 @@ class VlkbAmqp implements Vlkb
       boolean countNullValues, FitsCard[] extraCards)
          throws IOException, InterruptedException
       {
-         LOGGER.info("trace: " + pos.toString() );
+         LOGGER.fine("trace: " + pos.toString() );
 
          CutResult cutResult = new CutResult();
 
-         LOGGER.info("Using AMQP");
+         LOGGER.finer("Using AMQP");
 
          JsonEncoder jReq = new JsonEncoder();
          jReq.add(relPathname, hdunum);
@@ -113,7 +113,7 @@ class VlkbAmqp implements Vlkb
          boolean countNullValues, Subsurvey[] subsurveys)
          throws IOException, InterruptedException
       {
-         LOGGER.info("trace");
+         LOGGER.fine("trace");
 
          FitsCard[] extraCards = null;
 
@@ -128,7 +128,7 @@ class VlkbAmqp implements Vlkb
          }
          else
          {
-            LOGGER.info("Resolver returns subsurveyId null: no extraCards loaded.");
+            LOGGER.finer("Resolver returns subsurveyId null: no extraCards loaded.");
          }
 
          final String DEFAULT_TIME_SYSTEM = "MJD_UTC"; // FIXME take from confif file
@@ -148,13 +148,13 @@ class VlkbAmqp implements Vlkb
    public MCutResult doMCutout(String jdlJson)
          throws IOException
       {
-         LOGGER.info("trace");
+         LOGGER.fine("trace");
 
          MCutResult mCutResult;
 
-         LOGGER.info("doMCutout over AMQP");
+         LOGGER.finer("doMCutout over AMQP");
          String updatedJsonString = JdlMCutout.resolveAndUpdateJsonRequest(jdlJson, settings, subsurveys);
-         LOGGER.info("doMCutout over AMQP : " + updatedJsonString);
+         LOGGER.finest("doMCutout over AMQP : " + updatedJsonString);
          String outJson = RpcOverAmqp.doRpc(settings.amqpConn,  JdlMCutout.mcutoutToJson(updatedJsonString) );
          mCutResult = JdlMCutout.responseFromMCutoutJson(outJson);
 
@@ -199,9 +199,9 @@ class VlkbAmqp implements Vlkb
       //Subsurvey.subsurveysFindCards(subsurveys, rsl.obsCollection());//rsl.subsurveyId);
       String absSubimgPathname = settings.fitsPaths.cutouts() + "/"
          + generateSubimgPathname(rsl.relPathname(), rsl.hdunum());
-      LOGGER.info("absSubimgPathname: " + absSubimgPathname);
+      LOGGER.finest("absSubimgPathname: " + absSubimgPathname);
 
-      LOGGER.info("Using AMQP");
+      LOGGER.finer("Using AMQP");
 
       JsonEncoder jReq = new JsonEncoder();
       jReq.add(rsl.relPathname(), rsl.hdunum());
@@ -223,7 +223,7 @@ class VlkbAmqp implements Vlkb
 
    protected CutResult merge(String[] pubdids, Coord coord, Boolean countNullValues)
    {
-      LOGGER.info("trace");
+      LOGGER.fine("trace");
 
       ArrayList<CutResult> allresults = new ArrayList<CutResult>();
 
@@ -256,7 +256,7 @@ class VlkbAmqp implements Vlkb
             Boolean changed = grid.regrid_vel2(allCutPathnames);
             if(changed){
                //allresults.add("MSG Keywords CDELT3, CRVAL3 were adjusted for merge regridding.");
-               LOGGER.info("MSG Keywords CDELT3, CRVAL3 were adjusted for merge regridding.");
+               LOGGER.finer("MSG Keywords CDELT3, CRVAL3 were adjusted for merge regridding.");
             }
          }
 
@@ -308,7 +308,7 @@ class VlkbAmqp implements Vlkb
          String prefix,          // IN prefix added after filename-start-word
          String[] filestomerge)  // IN abs path with filenames to be merged
    {
-      LOGGER.info("trace");
+      LOGGER.fine("trace");
 
       String InJson = JsonEncoderMerge.mergefilesToJson( prefix, filestomerge);
       String OutJson = RpcOverAmqp.doRpc(settings.amqpConn, InJson);
@@ -325,10 +325,10 @@ class VlkbAmqp implements Vlkb
          String prefix,          // IN prefix added after filename-start-word
          String[] filestomerge)  // IN abs path with filenames to be merged
    {
-      LOGGER.info("mergefiles_parallel()");
+      LOGGER.fine("trace");
 
       String[] responseCH = mergefiles_common_header(jobId, logfilename, prefix, filestomerge);
-      for(String sentence : responseCH) VlkbAmqp.LOGGER.info("responseCmnHdr: " + sentence);
+      for(String sentence : responseCH) VlkbAmqp.LOGGER.finest("responseCmnHdr: " + sentence);
       // check if response errored -> abort with 500: Internal Server Error & log details
 
       int threadsCount = filestomerge.length;
@@ -360,7 +360,7 @@ class VlkbAmqp implements Vlkb
          }
 
 
-         for(String sentence : reprojectArr[i].response) VlkbAmqp.LOGGER.info("response[" + String.valueOf(i) + "]: " + sentence);
+         for(String sentence : reprojectArr[i].response) VlkbAmqp.LOGGER.finest("response[" + String.valueOf(i) + "]: " + sentence);
          if(!isResponseOk(reprojectArr[i].response))
          {
             ;// FIXME response incorrect -> abort merge-job, free resources
@@ -391,7 +391,7 @@ class VlkbAmqp implements Vlkb
          String prefix,          // IN prefix added after filename-start-word
          String[] filestomerge)  // IN abs path with filenames to be merged
    {
-      LOGGER.info("mergefiles_split_execution()");
+      LOGGER.fine("trace");
 
       String[] responseCH = mergefiles_common_header(jobId, logfilename, prefix, filestomerge);
       // check if response errored -> abort with 500: Internal Server Error & log details
@@ -414,7 +414,7 @@ class VlkbAmqp implements Vlkb
          String prefix,          // IN prefix added after filename-start-word
          String[] filestomerge)  // IN abs path with filenames to be merged
    {
-      LOGGER.info("trace");
+      LOGGER.fine("trace");
 
       String InJson = JsonEncoderMerge.mergefilesCommonHeaderToJson(jobId, prefix, filestomerge);
       String OutJson = RpcOverAmqp.doRpc(settings.amqpConn, InJson);
@@ -429,7 +429,7 @@ class VlkbAmqp implements Vlkb
          String prefix,          // IN prefix added after filename-start-word
          String fitsfilename)    // IN logfilename without path
    {
-      LOGGER.info("trace");
+      LOGGER.fine("trace");
 
       String InJson = JsonEncoderMerge.mergefilesReprojectToJson(jobId, prefix, fitsfilename);
       String OutJson = RpcOverAmqp.doRpc(settings.amqpConn, InJson);
@@ -443,7 +443,7 @@ class VlkbAmqp implements Vlkb
          String jobId,     // IN jobId to distinguish parallel executed requests
          String prefix)          // IN prefix added after filename-start-word
    {
-      LOGGER.info("trace");
+      LOGGER.fine("trace");
 
       String InJson = JsonEncoderMerge.mergefilesAddReprojectedToJson(jobId, prefix);
       String OutJson = RpcOverAmqp.doRpc(settings.amqpConn, InJson);
@@ -462,7 +462,7 @@ class VlkbAmqp implements Vlkb
    // -- from cutout: the cutout filename (server local)
    private String[] selectCutPathnames(CutResult[] results) {
 
-      LOGGER.info("selectCutPathnames()");
+      LOGGER.fine("trace");
 
       // return only data (without MSG's LOG's etc)
       ArrayList<String> data = new ArrayList<String>();
@@ -470,7 +470,7 @@ class VlkbAmqp implements Vlkb
       // sanity check - move after doFunc call (here covered by exception)
       // FIXME consider catch null-pointer-exception
       if(results == null) {
-         LOGGER.info("selectCutPathnames: results-table is null.");
+         LOGGER.finest("selectCutPathnames: results-table is null.");
          return null;
       }
 
@@ -489,8 +489,8 @@ class VlkbAmqp implements Vlkb
          String localfname = res.substring(4);//.replaceAll(FITScutpath, "");
          String[] ssfn = localfname.split(":");
          //String[] ssfn = localfname.substring(4).split(":");
-         LOGGER.info("ssfn[0]: " + ssfn[0]);
-         LOGGER.info("ssfn[1]: " + ssfn[1]);
+         LOGGER.finest("ssfn[0]: " + ssfn[0]);
+         LOGGER.finest("ssfn[1]: " + ssfn[1]);
          data.add(ssfn[1]);
          //data.add(localfname);
          break;
diff --git a/data-access/servlet/src/main/java/ops/VlkbCli.java b/data-access/servlet/src/main/java/ops/VlkbCli.java
index f49b229..f10ff25 100644
--- a/data-access/servlet/src/main/java/ops/VlkbCli.java
+++ b/data-access/servlet/src/main/java/ops/VlkbCli.java
@@ -39,7 +39,7 @@ import vo.parameter.*;
 
 class VlkbCli implements Vlkb
 {
-   static final Logger LOGGER = Logger.getLogger("VlkbCli");
+   static final Logger LOGGER = Logger.getLogger(VlkbCli.class.getName());
 
    private Settings    settings   = null;
    private Subsurvey[] subsurveys = null;
@@ -49,7 +49,7 @@ class VlkbCli implements Vlkb
 
    public VlkbCli()
    {
-      LOGGER.info("trace VlkbCli()");
+      LOGGER.fine("trace VlkbCli()");
       this.settings = Settings.getInstance();
       this.soda = new SodaImpl(settings.fitsPaths);
       this.resolver = (settings.dbConn.isDbUriEmpty() ? new ResolverFromId(subsurveys)
@@ -59,7 +59,7 @@ class VlkbCli implements Vlkb
 
    public VlkbCli(Settings settings)
    {
-      LOGGER.info("trace VlkbCli(settings)");
+      LOGGER.fine("trace VlkbCli(settings)");
       this.settings = settings;
       this.soda = new SodaImpl(settings.fitsPaths);
       this.resolver = (settings.dbConn.isDbUriEmpty() ? new ResolverFromId(subsurveys)
@@ -69,7 +69,7 @@ class VlkbCli implements Vlkb
 
    public VlkbCli(Settings settings, Subsurvey[] subsurveys)
    {
-      LOGGER.info("trace VlkbCli(settings, subsurveys)");
+      LOGGER.fine("trace VlkbCli(settings, subsurveys)");
       this.settings = settings;
       this.subsurveys = subsurveys;
       this.soda = new SodaImpl(settings.fitsPaths);
@@ -82,7 +82,7 @@ class VlkbCli implements Vlkb
    public CutResult doMerge(String[] idArr, Coord coord, boolean countNullValues)
       throws FileNotFoundException, IOException
    {
-      LOGGER.info("trace doMerge by CLI is NOT IMPLEMENTED (only by AMQP)");
+      LOGGER.fine("trace doMerge by CLI is NOT IMPLEMENTED (only by AMQP)");
 
       return new CutResult();
    }
@@ -94,16 +94,16 @@ class VlkbCli implements Vlkb
          boolean countNullValues, FitsCard[] extraCards)
          throws IOException, InterruptedException
       {
-         LOGGER.info("trace: " + pos.toString() );
+         LOGGER.fine("trace: " + pos.toString() );
 
          CutResult cutResult = new CutResult();
 
-         LOGGER.info("Using doStream() to local file");
+         LOGGER.finer("Using doStream() to local file");
 
          String absSubimgPathname = settings.fitsPaths.cutouts()
             + "/" + generateSubimgPathname(relPathname, hdunum);
 
-         LOGGER.info("Uses local filename : " + absSubimgPathname);
+         LOGGER.finer("Uses local filename : " + absSubimgPathname);
 
          OutputStream fileOutputStream = new FileOutputStream( new File(absSubimgPathname) );
 
@@ -120,7 +120,7 @@ class VlkbCli implements Vlkb
 
          if(extraCards == null || (extraCards.length < 1))
          {
-            LOGGER.info("Adding extraCards to cut-file implemented only in VlkbAmql");
+            LOGGER.finer("Adding extraCards to cut-file implemented only in VlkbAmql");
          }
 
          cutResult.pixels = null;
@@ -143,7 +143,7 @@ class VlkbCli implements Vlkb
 
          ExecCmd exec = new ExecCmd();
          exec.doRun(bos, cmdBounds);
-         LOGGER.info("exec NullVals exitValue: " + exec.exitValue);
+         LOGGER.finest("exec NullVals exitValue: " + exec.exitValue);
 
          bos.close();
 
@@ -151,7 +151,7 @@ class VlkbCli implements Vlkb
          if(hasResult)
          {
             String nullValsString = new String(bos.toByteArray());
-            LOGGER.info("vlkb nullvals: " + nullValsString);
+            LOGGER.finest("vlkb nullvals: " + nullValsString);
 
             if((nullValsString != null) && nullValsString.trim().isEmpty())
             {
@@ -183,7 +183,7 @@ class VlkbCli implements Vlkb
          boolean countNullValues/*, Subsurvey[] subsurveys*/)
          throws IOException, InterruptedException
       {
-         LOGGER.info("trace");
+         LOGGER.fine("trace");
 
          FitsCard[] extraCards = null;
 
@@ -198,7 +198,7 @@ class VlkbCli implements Vlkb
          }
          else
          {
-            LOGGER.info("Resolver returns subsurveyId null: no extraCards loaded.");
+            LOGGER.finer("Resolver returns subsurveyId null: no extraCards loaded.");
          }
 
          final String DEFAULT_TIME_SYSTEM = "MJD_UTC"; // FIXME take from confif file
@@ -237,7 +237,7 @@ class VlkbCli implements Vlkb
    public MCutResult doMCutout(String jdlJson)
          throws IOException, InterruptedException
       {
-         LOGGER.info("trace");
+         LOGGER.fine("trace");
 
          MCutResult mCutResult;
 
@@ -253,7 +253,7 @@ class VlkbCli implements Vlkb
 
    private MCutResult.Cut[] doCutouts(CutArgs[] cutArgsArr)
    {
-      LOGGER.info("trace, count of cuts : " + String.valueOf( cutArgsArr.length ) );
+      LOGGER.fine("trace, count of cuts : " + String.valueOf( cutArgsArr.length ) );
 
       List<MCutResult.Cut> cutResList = new ArrayList<MCutResult.Cut>();
 
@@ -266,7 +266,7 @@ class VlkbCli implements Vlkb
 
          cut.index = ix++;
 
-         LOGGER.info("cut" + String.valueOf(cut.index) + " : " + cut.content);
+         LOGGER.finest("cut" + String.valueOf(cut.index) + " : " + cut.content);
 
          cutResList.add(cut);
       }
@@ -297,7 +297,7 @@ class VlkbCli implements Vlkb
 
          for(MCutResult.Cut cut : cutArr)
          {
-            LOGGER.info("cut-id"+ String.valueOf(cut.index) + " -> " + cut.content);
+            LOGGER.finest("cut-id"+ String.valueOf(cut.index) + " -> " + cut.content);
             if(cut.contentType == MCutResult.Cut.ContentType.FILENAME)
             {
                Path p = Paths.get(cut.content);
@@ -336,7 +336,7 @@ class VlkbCli implements Vlkb
    private MCutResult.Cut doFileByIdWithErr(String id, Pos pos, Band band, Time time, Pol pol, String pixels,
          boolean countNullValues/*, Subsurvey[] subsurveys*/)
    {
-      LOGGER.info("trace");
+      LOGGER.fine("trace");
 
       MCutResult mCutResult = new MCutResult();
       MCutResult.Cut cut = mCutResult.new Cut(/* FIXME eventually add here new Inputs(id, pos,..) */);
@@ -354,19 +354,19 @@ class VlkbCli implements Vlkb
       {
          cut.content = "MultiValuedParamNotSupported: " + ex.getMessage();
          cut.contentType = MCutResult.Cut.ContentType.BAD_REQUEST;
-         LOGGER.info(cut.content);
+         LOGGER.warning(cut.content);
       }
       catch(IllegalArgumentException ex) 
       {
          cut.content = "IllegalArgumentException: " + ex.getMessage();
          cut.contentType = MCutResult.Cut.ContentType.BAD_REQUEST;
-         LOGGER.info(cut.content);
+         LOGGER.warning(cut.content);
       }
       catch(Exception ex) 
       {
          cut.content     = "Exception: " + ex.getMessage();
          cut.contentType = MCutResult.Cut.ContentType.SERVICE_ERROR;
-         LOGGER.info(cut.content);
+         LOGGER.severe(cut.content);
          ex.printStackTrace();
       }
 
diff --git a/data-access/servlet/src/main/java/ops/amqp/JsonDecoder.java b/data-access/servlet/src/main/java/ops/amqp/JsonDecoder.java
index 93263e8..cfc3b72 100644
--- a/data-access/servlet/src/main/java/ops/amqp/JsonDecoder.java
+++ b/data-access/servlet/src/main/java/ops/amqp/JsonDecoder.java
@@ -31,7 +31,7 @@ import org.json.simple.parser.ParseException;
 
 public class JsonDecoder
 {
- static final Logger LOGGER = Logger.getLogger("JsonDecoder");
+ static final Logger LOGGER = Logger.getLogger(JsonDecoder.class.getName());
 
    public static CutResult responseFromCutoutJson(String response)
       // throws ParseException
@@ -77,7 +77,7 @@ public class JsonDecoder
       }
       catch  (ParseException e)
       {
-         LOGGER.info(e.getMessage());
+         LOGGER.severe(e.getMessage());
          e.printStackTrace();
          throw new IllegalStateException("Internal system error.");
       }
diff --git a/data-access/servlet/src/main/java/ops/amqp/JsonEncoder.java b/data-access/servlet/src/main/java/ops/amqp/JsonEncoder.java
index 0891848..52a8a43 100644
--- a/data-access/servlet/src/main/java/ops/amqp/JsonEncoder.java
+++ b/data-access/servlet/src/main/java/ops/amqp/JsonEncoder.java
@@ -12,7 +12,7 @@ import vo.parameter.*;
 
 public class JsonEncoder
 {
-   static final Logger LOGGER = Logger.getLogger("JsonEncoder");
+   static final Logger LOGGER = Logger.getLogger(JsonEncoder.class.getName());
 
    private JSONObject obj;
 
@@ -23,8 +23,6 @@ public class JsonEncoder
 
    public void add(String pathname, int hdunum)
    {
-      LOGGER.info("trace" + pathname);
-
       this.obj.put("img_pathname", pathname);
       this.obj.put("img_hdunum",   hdunum);
    }
@@ -35,6 +33,8 @@ public class JsonEncoder
 
    public void add(Pos pos)
    {
+      LOGGER.fine("trace");
+
       if(pos != null)
       {
          JSONObject j = new JSONObject();
diff --git a/data-access/servlet/src/main/java/ops/amqp/RpcOverAmqp.java b/data-access/servlet/src/main/java/ops/amqp/RpcOverAmqp.java
index ff4068e..8aa1b1a 100644
--- a/data-access/servlet/src/main/java/ops/amqp/RpcOverAmqp.java
+++ b/data-access/servlet/src/main/java/ops/amqp/RpcOverAmqp.java
@@ -25,7 +25,7 @@ import java.util.UUID;
 
 public class RpcOverAmqp
 {
- private static final Logger LOGGER = Logger.getLogger("RpcOverAmqp");
+ private static final Logger LOGGER = Logger.getLogger(RpcOverAmqp.class.getName());
 
 	private final boolean NO_ACK = true;
 	// affects message consume from queue:
@@ -48,6 +48,8 @@ public class RpcOverAmqp
 
  public static String doRpc(Settings.AmqpConn  amqpConn, String InStr)
    {
+      LOGGER.fine("trace");
+
       final String userName = "guest";
       final String password = "guest";
       // FIXME move these to Settings
@@ -64,13 +66,13 @@ public class RpcOverAmqp
 
       try
       {
-         LOGGER.info("Sent request : " + InStr);
+         LOGGER.finer("Sent request : " + InStr);
          OutStr = rpc.callAndWaitReply(InStr);
-         LOGGER.info("Got response : " + OutStr);
+         LOGGER.finer("Got response : " + OutStr);
       }
       catch  (Exception e)
       {
-         e.printStackTrace();
+         LOGGER.severe("Exception: " + e.getMessage());
       }
       finally
       {
@@ -80,7 +82,7 @@ public class RpcOverAmqp
          }
          catch (Exception ignore)
          {
-            LOGGER.info("ignoring exception on rpc.close():" + ignore.getMessage());
+            LOGGER.finer("ignoring exception on rpc.close():" + ignore.getMessage());
          }
       }
 
@@ -122,7 +124,7 @@ public class RpcOverAmqp
 		}
 		catch(Exception e)
 		{
-			e.printStackTrace();
+			LOGGER.severe("Exception: " + e.getMessage());
 		}
 	}
 
@@ -150,7 +152,7 @@ public class RpcOverAmqp
 
 			QueueingConsumer.Delivery delivery = consumer.nextDelivery();
 
-			System.out.println("CorrId sent[" + channelNumber + "]: "  + delivery.getProperties().getCorrelationId()
+			LOGGER.finest("CorrId sent[" + channelNumber + "]: "  + delivery.getProperties().getCorrelationId()
 					+ "\nCorrId recv: " + corrId
 					+ "\nreplyQueueName: " +  replyQueueName);
 
diff --git a/data-access/servlet/src/main/java/ops/cli/ExecCmd.java b/data-access/servlet/src/main/java/ops/cli/ExecCmd.java
index 43f7692..cee6e77 100644
--- a/data-access/servlet/src/main/java/ops/cli/ExecCmd.java
+++ b/data-access/servlet/src/main/java/ops/cli/ExecCmd.java
@@ -6,7 +6,7 @@ import java.io.*;
 
 class StreamGobbler extends Thread
 {
-   public static final Logger LOGGER = Logger.getLogger("StreamGobbler");
+   public static final Logger LOGGER = Logger.getLogger(StreamGobbler.class.getName());
 
    InputStream is;
    String type;
@@ -19,6 +19,7 @@ class StreamGobbler extends Thread
 
    StreamGobbler(InputStream is, String type, OutputStream redirect)
    {
+      LOGGER.fine("trace");
       this.is = is;
       this.type = type;
       this.os = redirect;
@@ -27,6 +28,8 @@ class StreamGobbler extends Thread
 
    public void run()
    {
+      LOGGER.fine("trace");
+
       try
       {
          BufferedOutputStream bos = null;
@@ -45,7 +48,7 @@ class StreamGobbler extends Thread
             }
             else
             {
-               LOGGER.info(type + ">" + new String(buffer, 0, nread, "utf-8"));
+               LOGGER.finest(type + ">" + new String(buffer, 0, nread, "utf-8"));
             }
          }
 
@@ -62,16 +65,16 @@ class StreamGobbler extends Thread
 
 class ExecCmd
 {
-   public static final Logger LOGGER = Logger.getLogger("ExecCmd");
+   public static final Logger LOGGER = Logger.getLogger(ExecCmd.class.getName());
 
    public int exitValue;
 
    public void doRun(OutputStream outputStream, String[] cmd)
       throws IOException, InterruptedException
    {
-      // Assert outputStream != null
+      LOGGER.fine("trace CMD: " + Arrays.toString(cmd));
 
-      LOGGER.info("CMD: " + Arrays.toString(cmd));
+      // Assert outputStream != null
 
       long start_nsec = System.nanoTime();
 
@@ -103,7 +106,7 @@ class ExecCmd
 
       long meas4_nsec = System.nanoTime();
 
-      LOGGER.info("RUNTIME[nsec] ExecCmd::doRun(): "
+      LOGGER.finer("RUNTIME[nsec] ExecCmd::doRun(): "
             +       String.valueOf((long)Math.round( (meas1_nsec - start_nsec)/1.0e6 ))
             + " " + String.valueOf((long)Math.round( (meas2_nsec - start_nsec)/1.0e6 ))
             + " " + String.valueOf((long)Math.round( (meas3_nsec - start_nsec)/1.0e6 ))
diff --git a/data-access/servlet/src/main/java/resolver/ResolverByObsCore.java b/data-access/servlet/src/main/java/resolver/ResolverByObsCore.java
index b2a101d..d2490f2 100644
--- a/data-access/servlet/src/main/java/resolver/ResolverByObsCore.java
+++ b/data-access/servlet/src/main/java/resolver/ResolverByObsCore.java
@@ -30,25 +30,25 @@ class ResolverByObsCore implements Resolver
 
    public void resolve(String pubdid)
    {
-      LOGGER.info("trace " + pubdid);
+      LOGGER.fine("trace " + pubdid);
       try
       {
          resolveByMapping(pubdid, dbConn);
       }
       catch(ClassNotFoundException e)
       {
-         LOGGER.info("DB driver class was not loaded. No database connection.");
+         LOGGER.severe("DB driver class was not loaded. No database connection.");
       }
-      LOGGER.info("relPathname   : " + relPathname);
-      LOGGER.info("hdunum        : " + String.valueOf(hdunum));
-      LOGGER.info("obsCollection : " + this.subsurveyId);
+      LOGGER.finer("relPathname   : " + relPathname);
+      LOGGER.finer("hdunum        : " + String.valueOf(hdunum));
+      LOGGER.finer("obsCollection : " + this.subsurveyId);
    }
 
 
 
    private void resolveByMapping(String pubdid, Settings.DBConn dbConn) throws ClassNotFoundException
    {
-      LOGGER.info("trace " + pubdid);
+      LOGGER.fine("trace " + pubdid);
 
       if(this.subsurveys == null)
       {
@@ -102,7 +102,7 @@ class ResolverByObsCore implements Resolver
    private void db_queryAccessUrlAndObsCollection(Settings.DBConn dbConn, String pubdid)//, String accessUrl, String obsCollection)
       throws ClassNotFoundException
    {
-      LOGGER.info("trace");
+      LOGGER.fine("trace");
 
       ResolverByObsCoreDb rdb;
       synchronized(ResolverByObsCoreDb.class)
diff --git a/data-access/servlet/src/main/java/resolver/ResolverByObsCoreDb.java b/data-access/servlet/src/main/java/resolver/ResolverByObsCoreDb.java
index 5f80c98..57847af 100644
--- a/data-access/servlet/src/main/java/resolver/ResolverByObsCoreDb.java
+++ b/data-access/servlet/src/main/java/resolver/ResolverByObsCoreDb.java
@@ -43,7 +43,7 @@ public class ResolverByObsCoreDb
       conn = null;
       st   = null;
       res  = null;
-      //LOGGER.info("Loading DB driver: " + DB_DRIVER);
+      //LOGGER.finer("Loading DB driver: " + DB_DRIVER);
       //Class.forName(DB_DRIVER);
    }
 
@@ -54,11 +54,11 @@ public class ResolverByObsCoreDb
 
       String TheQuery = "SELECT access_url,obs_collection FROM obscore "
          + "WHERE obs_publisher_did = \'"+ obsPubdid +"\'";
-      LOGGER.info(TheQuery);
+      LOGGER.finest(TheQuery);
 
       String[] results = new String[2];
 
-      LOGGER.info("Connecting to: " + dbconn.uri() + " with optional user/pwd: " + dbconn.userName() + " / " + dbconn.password() );
+      LOGGER.finer("Connecting to: " + dbconn.uri() + " with optional user/pwd: " + dbconn.userName() + " / " + dbconn.password() );
 
       try(
             Connection conn = DriverManager.getConnection(dbconn.uri(), dbconn.userName(), dbconn.password());
@@ -69,7 +69,7 @@ public class ResolverByObsCoreDb
 
          if(res == null)
          {
-            LOGGER.info("Pubdid not in the db: " + pubdid);
+            LOGGER.finest("Pubdid not in the db: " + pubdid);
             return null;
          };
 
@@ -91,7 +91,7 @@ public class ResolverByObsCoreDb
       }
 /*      catch (ClassNotFoundException e)
       {
-         LOGGER.info("DB driver "+ DB_DRIVER +" not found: " + e.getMessage());
+         LOGGER.severe("DB driver "+ DB_DRIVER +" not found: " + e.getMessage());
          e.printStackTrace();
       }
             finally
@@ -121,12 +121,12 @@ public class ResolverByObsCoreDb
 
    private void logSqlExInfo(SQLException se)
    {
-      LOGGER.info("SQLState : " + se.getSQLState());
-      LOGGER.info("ErrorCode: " + se.getErrorCode());
-      LOGGER.info("Message  : " + se.getMessage());
+      LOGGER.finer("SQLState : " + se.getSQLState());
+      LOGGER.finer("ErrorCode: " + se.getErrorCode());
+      LOGGER.finer("Message  : " + se.getMessage());
       Throwable t = se.getCause();
       while(t != null) {
-         LOGGER.info("Cause: " + t);
+         LOGGER.finer("Cause: " + t);
          t = t.getCause();
       }
    }
@@ -143,11 +143,11 @@ public class ResolverByObsCoreDb
 //    Class.forName(DB_DRIVER);
    /* OR
     * DriverManager.registerDriver(new org.postgresql.Driver());
-    * LOGGER.info(getClasspathString());
-    * LOGGER.info(getRegisteredDriverList());
+    * LOGGER.finest(getClasspathString());
+    * LOGGER.finest(getRegisteredDriverList());
     * /
 
-    LOGGER.info("Connecting to: " + dbconn.uri() + " with optional user/pwd: " + dbconn.userName() + " / " + dbconn.password() );
+    LOGGER.finer("Connecting to: " + dbconn.uri() + " with optional user/pwd: " + dbconn.userName() + " / " + dbconn.password() );
 
 //    Connection conn = DriverManager.getConnection(dbconn.uri(), dbconn.userName(), dbconn.password());
 
diff --git a/data-access/servlet/src/main/java/resolver/ResolverFromId.java b/data-access/servlet/src/main/java/resolver/ResolverFromId.java
index 95ee9ec..847aa6a 100644
--- a/data-access/servlet/src/main/java/resolver/ResolverFromId.java
+++ b/data-access/servlet/src/main/java/resolver/ResolverFromId.java
@@ -25,7 +25,7 @@ class ResolverFromId implements Resolver
 
    public void resolve(String pubdid)
    {
-      LOGGER.info("trace " + pubdid);
+      LOGGER.fine("trace " + pubdid);
 
       boolean isIvoid = pubdid.substring(0,6).equals("ivo://");
 
@@ -35,9 +35,9 @@ class ResolverFromId implements Resolver
 
          // FIXME resolve subsurveyId by matching relPathname to subsurveys::storage-path & file-filter
 
-         LOGGER.info("relPathname : " + relPathname);
-         LOGGER.info("hdunum      : " + String.valueOf(hdunum));
-         LOGGER.info("subsurveyId : " + ((subsurveyId == null) ? "null" : this.subsurveyId) );
+         LOGGER.finer("relPathname : " + relPathname);
+         LOGGER.finer("hdunum      : " + String.valueOf(hdunum));
+         LOGGER.finer("subsurveyId : " + ((subsurveyId == null) ? "null" : this.subsurveyId) );
       }
       else
       {
@@ -49,7 +49,7 @@ class ResolverFromId implements Resolver
 
    private void resolveIvoid(String pubdid)
    {
-      LOGGER.info("trace " + pubdid);
+      LOGGER.fine("trace " + pubdid);
 
       int qmarkIx = pubdid.lastIndexOf("?");
       int dhashIx = pubdid.lastIndexOf("#");// returns -1 if hash not found
diff --git a/data-access/servlet/src/main/java/webapi/AuthZFilter.java b/data-access/servlet/src/main/java/webapi/AuthZFilter.java
index c2b94e1..d24628f 100644
--- a/data-access/servlet/src/main/java/webapi/AuthZFilter.java
+++ b/data-access/servlet/src/main/java/webapi/AuthZFilter.java
@@ -37,7 +37,7 @@ import java.io.ByteArrayOutputStream;
 
 class AuthZ
 {
-   private static final Logger LOGGER = Logger.getLogger("AuthZ");
+   private static final Logger LOGGER = Logger.getLogger(AuthZ.class.getName());
    private static final AuthZSettings settings = AuthZSettings.getInstance("authpolicy.properties");
 
    List<String> pubdidList = new ArrayList<String>();
@@ -47,7 +47,7 @@ class AuthZ
 
    public AuthZ(HttpServletRequest req) throws IOException, ServletException
    {
-      LOGGER.info("constructor");
+      LOGGER.fine("constructor");
 
       String[] pubdidArr = req.getParameterValues("ID");
       if(pubdidArr == null)
@@ -61,7 +61,7 @@ class AuthZ
          for(String pubdid : pubdidArr)
             if(pubdid.length() > 0) pubdidList.add(pubdid);
 
-         LOGGER.info("pubdids: " + String.join(" ", pubdidList));
+         LOGGER.finest("pubdids: " + String.join(" ", pubdidList));
       }
    }
 
@@ -82,7 +82,7 @@ class AuthZ
 
    public boolean isAuthorized(HttpServletRequest req)
    {
-      LOGGER.info("isAuthorized");
+      LOGGER.fine("isAuthorized");
 
       AuthPolicy auth = null;
       try
@@ -113,7 +113,7 @@ class AuthZ
 @javax.servlet.annotation.MultipartConfig
 public class AuthZFilter implements Filter
 {
-   private static final Logger LOGGER = Logger.getLogger("AuthZFilter");
+   private static final Logger LOGGER = Logger.getLogger(AuthZFilter.class.getName());
 
 
    @Override
@@ -125,7 +125,7 @@ public class AuthZFilter implements Filter
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
    {
-      LOGGER.info("doFilter");
+      LOGGER.fine("doFilter");
 
       HttpServletRequest  req  = (HttpServletRequest)  request;
       HttpServletResponse  resp = (HttpServletResponse)  response;
diff --git a/data-access/servlet/src/main/java/webapi/AuthZSettings.java b/data-access/servlet/src/main/java/webapi/AuthZSettings.java
index 7cd7e6a..ecb811e 100644
--- a/data-access/servlet/src/main/java/webapi/AuthZSettings.java
+++ b/data-access/servlet/src/main/java/webapi/AuthZSettings.java
@@ -9,7 +9,7 @@ import java.io.PrintWriter;
 
 class AuthZSettings
 {
-   private static final Logger LOGGER = Logger.getLogger("AuthZSettings");
+   private static final Logger LOGGER = Logger.getLogger(AuthZSettings.class.getName());
 
    public static class DBConn
    {
@@ -36,6 +36,8 @@ class AuthZSettings
    // no reasonable code-defaults can be invented
    public static AuthZSettings getInstance(String propertiesFilename)
    {
+      LOGGER.config("reading settings from : " + propertiesFilename);
+
       try
       {
          InputStream ins =
@@ -72,6 +74,8 @@ class AuthZSettings
 
    private static DBConn loadDBConn(Properties properties)
    {
+      LOGGER.fine("trace");
+
       DBConn dbconn = new AuthZSettings.DBConn();
       dbconn.uri       = properties.getProperty("db_uri", "jdbc:postgresql://localhost:5432/vialactea").strip();
       dbconn.schema    = properties.getProperty("db_schema", "datasets").strip();
diff --git a/data-access/servlet/src/main/java/webapi/ServletCutout.java b/data-access/servlet/src/main/java/webapi/ServletCutout.java
index c2ad072..4591099 100644
--- a/data-access/servlet/src/main/java/webapi/ServletCutout.java
+++ b/data-access/servlet/src/main/java/webapi/ServletCutout.java
@@ -1,5 +1,6 @@
 
 import java.util.logging.Logger;
+import java.util.logging.Level;
 
 import java.security.Principal;
 
@@ -46,7 +47,7 @@ import vo.parameter.*;
 
 public class ServletCutout extends HttpServlet
 {
-   protected static final Logger      LOGGER     = Logger.getLogger("ServletCutout");
+   protected static final Logger      LOGGER     = Logger.getLogger(ServletCutout.class.getName());
    protected static final Settings    settings   = Settings.getInstance();
    protected static final Subsurvey[] subsurveys = Subsurvey.loadSubsurveys(settings.fitsPaths.surveysMetadataAbsPathname());
 
@@ -61,15 +62,15 @@ public class ServletCutout extends HttpServlet
 
    public void init() throws ServletException
    {
-     LOGGER.info("FITS : " + settings.fitsPaths.toString());
+     LOGGER.config("FITS : " + settings.fitsPaths.toString());
       if(subsurveys != null)
-         LOGGER.info("Subsurveys loaded : " + String.valueOf(subsurveys.length));
-      LOGGER.info("DEFAULT SKY/SPEC/TIME SYSTEM : " + DEFAULT_SKY_SYSTEM + " / " + DEFAULT_SPEC_SYSTEM + " / " + DEFAULT_TIME_SYSTEM);
-      LOGGER.info("DEFAULT_RESPONSEFORMAT : " + DEFAULT_RESPONSEFORMAT);
-      LOGGER.info("Resolver : " + (resolveFromId    ? "IVOID" : "DB"));
-      LOGGER.info("Engine   : " + (useEngineOverCli ? "CLI"   : "AMQP"));
+         LOGGER.config("Subsurveys loaded : " + String.valueOf(subsurveys.length));
+      LOGGER.config("DEFAULT SKY/SPEC/TIME SYSTEM : " + DEFAULT_SKY_SYSTEM + " / " + DEFAULT_SPEC_SYSTEM + " / " + DEFAULT_TIME_SYSTEM);
+      LOGGER.config("DEFAULT_RESPONSEFORMAT : " + DEFAULT_RESPONSEFORMAT);
+      LOGGER.config("Resolver : " + (resolveFromId    ? "IVOID" : "DB"));
+      LOGGER.config("Engine   : " + (useEngineOverCli ? "CLI"   : "AMQP"));
       if(!useEngineOverCli)
-         LOGGER.info("AMQP : " + settings.amqpConn.toString());
+         LOGGER.config("AMQP : " + settings.amqpConn.toString());
    }
 
 
@@ -120,7 +121,7 @@ public class ServletCutout extends HttpServlet
    protected void doCutoutStream(String id, Pos pos, Band band, Time time, Pol pol, String pixels,
          OutputStream respOutputStream) throws IOException, InterruptedException
    {
-      LOGGER.info("trace" + pos);
+      LOGGER.fine("trace " + pos);
 
       final Resolver resolver = (resolveFromId ?
             new ResolverFromId(subsurveys) :
@@ -138,7 +139,7 @@ public class ServletCutout extends HttpServlet
          boolean countNullValues)
          throws IOException, InterruptedException
       {
-         LOGGER.info("trace");
+         LOGGER.fine("trace");
 
          FitsCard[] extraCards = null;
 
@@ -158,7 +159,7 @@ public class ServletCutout extends HttpServlet
          }
          else
          {
-            LOGGER.info("Resolver returns subsurveyId null: no extraCards loaded.");
+            LOGGER.fine("Resolver returns subsurveyId null: no extraCards loaded.");
          }
 
          return vlkb.doFile(resolver.relPathname(), resolver.hdunum(),
@@ -191,19 +192,19 @@ public class ServletCutout extends HttpServlet
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
          throws ServletException, IOException, UnsupportedEncodingException
       {
-
          final boolean NO_QUERY_STRING = (request.getQueryString() == null);
 
          if(NO_QUERY_STRING)
          {
             writeSodaDescriptor(request, response);
-            LOGGER.info("normal exit with SODA service descriptor");
+            LOGGER.fine("normal exit with SODA service descriptor");
             return;
          }
          else
          {
+            LOGGER.info(URLDecoder.decode(request.getQueryString(), "UTF-8"));
             execRequest(request, response);
-            LOGGER.info("normal exit");
+            LOGGER.fine("normal exit");
          }
       }
 
@@ -215,13 +216,14 @@ public class ServletCutout extends HttpServlet
          if(NO_QUERY_STRING)
          {
             writeSodaDescriptor(request, response);
-            LOGGER.info("normal exit with SODA service descriptor");
+            LOGGER.fine("normal exit with SODA service descriptor");
             return;
          }
          else
          {
+            LOGGER.info(URLDecoder.decode(request.getQueryString(), "UTF-8"));
             execRequest(request, response);
-            LOGGER.info("normal exit");
+            LOGGER.fine("normal exit");
          }
       }
 
@@ -261,7 +263,7 @@ public class ServletCutout extends HttpServlet
 
             String respFormat = sodaReq_getResponseFormat(request, DEFAULT_RESPONSEFORMAT);
 
-            LOGGER.info("responseFormat: " + respFormat);
+            LOGGER.finest("responseFormat: " + respFormat);
 
             if(respFormat.startsWith("application/fits"))
             {
@@ -299,7 +301,7 @@ public class ServletCutout extends HttpServlet
          }
          catch(MultiValuedParamNotSupported ex)
          {
-            LOGGER.info("MultiValuedParamNotSupported: " + ex.getMessage());
+            LOGGER.warning("MultiValuedParamNotSupported: " + ex.getMessage());
 
             response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
             response.setContentType("text/plain");
@@ -311,7 +313,7 @@ public class ServletCutout extends HttpServlet
          }
          catch(IllegalArgumentException ex)
          {
-            LOGGER.info("IllegalArgumentException: " + ex.getMessage());
+            LOGGER.warning("IllegalArgumentException: " + ex.getMessage());
 
             response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
             response.setContentType("text/plain");
@@ -323,7 +325,7 @@ public class ServletCutout extends HttpServlet
          }
          catch(Exception ex)
          {
-            LOGGER.info("Exception: " + ex.getMessage());
+            LOGGER.severe("Exception: " + ex.getMessage());
             ex.printStackTrace();
 
             response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
@@ -339,17 +341,17 @@ public class ServletCutout extends HttpServlet
             respOutputStream.close();
          }
 
-         LOGGER.info("RUNTIME[nsec] Servlet::execRequest: "+String.valueOf(System.nanoTime() - startTime_nsec));
+         LOGGER.fine("RUNTIME[sec]: "+String.valueOf( (System.nanoTime() - startTime_nsec) / 1000000000.0 ));
       }
 
    private String convertLocalPathnameToRemoteUrl(String localPathname,
          String FITScutpath, String FITSRemoteUrlCutouts)
    {
-      LOGGER.info("trace " + localPathname);
+      LOGGER.fine("trace " + localPathname);
       String fileName = localPathname.replaceAll(FITScutpath + "/", "");
-      LOGGER.info("local filename: " + fileName);
+      LOGGER.finest("local filename: " + fileName);
       String remotefname = FITSRemoteUrlCutouts + "/" + fileName;
-      LOGGER.info("remote url    : " + remotefname);
+      LOGGER.finest("remote url    : " + remotefname);
       return remotefname;
    }
 
diff --git a/data-access/servlet/src/main/java/webapi/UWSMCutoutWork.java b/data-access/servlet/src/main/java/webapi/UWSMCutoutWork.java
index 3d59890..df5e0e1 100644
--- a/data-access/servlet/src/main/java/webapi/UWSMCutoutWork.java
+++ b/data-access/servlet/src/main/java/webapi/UWSMCutoutWork.java
@@ -124,11 +124,11 @@ public class UWSMCutoutWork extends JobThread
    private String convertLocalPathnameToRemoteUrl(String localPathname,
          String FITScutpath, String FITSRemoteUrlCutouts)
    {
-      //LOGGER.info("trace " + localPathname);
+      //LOGGER.fine("trace " + localPathname);
       String fileName = localPathname.replaceAll(FITScutpath + "/", "");
-      //LOGGER.info("local filename: " + fileName);
+      //LOGGER.finer("local filename: " + fileName);
       String remotefname = FITSRemoteUrlCutouts + "/" + fileName;
-      //LOGGER.info("remote url    : " + remotefname);
+      //LOGGER.finer("remote url    : " + remotefname);
       return remotefname;
    }
 
diff --git a/data-access/servlet/src/main/java/webapi/UWSMergeWork.java b/data-access/servlet/src/main/java/webapi/UWSMergeWork.java
index 7d62fd8..230ddf3 100644
--- a/data-access/servlet/src/main/java/webapi/UWSMergeWork.java
+++ b/data-access/servlet/src/main/java/webapi/UWSMergeWork.java
@@ -147,11 +147,11 @@ public class UWSMergeWork extends JobThread
    private String convertLocalPathnameToRemoteUrl(String localPathname,
          String FITScutpath, String FITSRemoteUrlCutouts)
    {
-      //LOGGER.info("trace " + localPathname);
+      //LOGGER.fine("trace " + localPathname);
       String fileName = localPathname.replaceAll(FITScutpath + "/", "");
-      //LOGGER.info("local filename: " + fileName);
+      //LOGGER.finer("local filename: " + fileName);
       String remotefname = FITSRemoteUrlCutouts + "/" + fileName;
-      //LOGGER.info("remote url    : " + remotefname);
+      //LOGGER.finer("remote url    : " + remotefname);
       return remotefname;
    }
 
diff --git a/data-access/servlet/src/main/java/webapi/output/XmlSerializer.java b/data-access/servlet/src/main/java/webapi/output/XmlSerializer.java
index cc933cd..61f96b7 100644
--- a/data-access/servlet/src/main/java/webapi/output/XmlSerializer.java
+++ b/data-access/servlet/src/main/java/webapi/output/XmlSerializer.java
@@ -6,7 +6,7 @@ import vo.parameter.*;
 
 public final class XmlSerializer
 {
-   private static final Logger LOGGER = Logger.getLogger("XmlSerializer");
+   private static final Logger LOGGER = Logger.getLogger(XmlSerializer.class.getName());
 
    private XmlSerializer() {} // disables instatiation
 
@@ -15,7 +15,7 @@ public final class XmlSerializer
         String id, Pos pos, Band band, Time time, Pol pol, String pixels, boolean countNullValues,
          boolean showDuration, long startTime_msec)
   {
-     LOGGER.info("trace serialize for accessUrl: " + ((accessUrl==null)? "null":accessUrl));
+     LOGGER.fine("trace serialize for accessUrl: " + ((accessUrl==null)? "null":accessUrl));
 
      writer.println("<?xml version=\"1.0\" encoding=\"" + charEncoding + "\" standalone=\"yes\"?>");
      writer.println("<results>");
@@ -55,7 +55,7 @@ public final class XmlSerializer
         //String id, Pos pos, Band band, Time time, Pol pol, String pixels, boolean countNullValues,
          boolean showDuration, long startTime_msec)
   {
-     LOGGER.info("trace serialize for accessUrl: " + ((accessUrl==null)? "null":accessUrl));
+     LOGGER.fine("trace serialize for accessUrl: " + ((accessUrl==null)? "null":accessUrl));
 
      writer.println("<?xml version=\"1.0\" encoding=\"" + charEncoding + "\" standalone=\"yes\"?>");
      writer.println("<results>");
diff --git a/java-libs/lib/vlkb-volib-0.9.1-SNAPSHOT.jar b/java-libs/lib/vlkb-volib-0.9.1-SNAPSHOT.jar
index f1a6a61c90acada94ec801155a5adc9f30d1b1cd..4af8f63066eaec4a80adaabf4e4dd13fb30d47c3 100644
GIT binary patch
delta 9422
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
b4$c>0Y?+*qFT)g<0Tx)4FUQ7}2{HfxQy*rw

delta 9468
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
U@@1H$GQffl@>ST5Wq`~802v9UOaK4?

-- 
GitLab