Skip to content

Commit

Permalink
Improvements to logging
Browse files Browse the repository at this point in the history
  • Loading branch information
bhvkshah committed Apr 13, 2023
1 parent 985695f commit 037beb4
Show file tree
Hide file tree
Showing 4 changed files with 173 additions and 24 deletions.
7 changes: 6 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<artifactId>redshift-jdbc42</artifactId>
<packaging>bundle</packaging>
<name>Redshift JDBC Driver - JDBC 4.2</name>
<version>2.1.0.10</version>
<version>2.0.0.0</version>

<description>Java JDBC 4.2 (JRE 8+) driver for Redshift database</description>

Expand Down Expand Up @@ -116,6 +116,11 @@
<artifactId>classloader-leak-test-framework</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.15</version>
</dependency>
</dependencies>

<profiles>
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/amazon/redshift/Driver.java
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ public Connection connect(String url, Properties info) throws SQLException {
logger.log(LogLevel.DEBUG, "===================================");
logger.log(LogLevel.DEBUG, "Connecting with URL: {0}", temp);
connLogger.log(LogLevel.DEBUG, "===================================");
connLogger.logFunction(true, temp, RedshiftLogger.maskSecureInfoInProps(info));
connLogger.logFunction(true, temp, RedshiftLogger.maskSecureInfoInProps(props));

connLogger.log(LogLevel.DEBUG, "Connecting with URL: {0}", temp);
if(iniFileName != null) {
Expand Down
96 changes: 96 additions & 0 deletions src/main/java/com/amazon/redshift/RedshiftProperty.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.Collections;
import java.util.HashSet;
import java.util.Arrays;

/**
* All connection parameters that can be either set in JDBC URL, in Driver properties or in
Expand Down Expand Up @@ -1043,6 +1047,87 @@ public enum RedshiftProperty {
private final String[] choices;
private final boolean deprecated;

private static final Set<String> publicProperties = Collections.unmodifiableSet( new HashSet<>(Arrays.asList
(
"AccessKeyID"
,"AllowDBUserOverride"
,"App_ID"
,"App_Name"
,"ApplicationName"
,"AuthProfile"
,"AutoCreate"
,"Client_ID"
,"Client_Secret"
,"client_protocol_version"
,"ClusterID"
,"connectTimeout"
,"databaseMetadataCurrentDbOnly"
,"DbUser"
,"DbGroups"
,"DBNAME"
,"defaultRowFetchSize"
,"DisableIsValidQuery"
,"enableFetchReadAndProcessBuffers"
,"enableFetchRingBuffer"
,"enableMultiSqlSupport"
,"endpointUrl"
,"fetchRingBufferSize"
,"ForceLowercase"
,"groupFederation"
,"HOST"
,"IAMDisableCache"
,"IAMDuration"
,"IdP_Host"
,"IdP_Port"
,"IdP_Tenant"
,"IdP_Response_Timeout"
,"IniFile"
,"IniSection"
,"isServerless"
,"Login_URL"
,"loginTimeout"
,"loginToRp"
,"LogLevel"
,"LogPath"
,"OverrideSchemaPatternType"
,"Partner_SPID"
,"Password"
,"Plugin_Name"
,"PORT"
,"Preferred_Role"
,"Profile"
,"PWD"
,"queryGroup"
,"readOnly"
,"Region"
,"reWriteBatchedInserts"
,"reWriteBatchedInsertsSize"
,"roleArn"
,"roleSessionName"
,"scope"
,"SecretAccessKey"
,"SessionToken"
,"serverlessAcctId"
,"serverlessWorkGroup"
,"socketFactory"
,"socketTimeout"
,"SSL"
,"SSL_Insecure"
,"SSLCert"
,"SSLFactory"
,"SSLKey"
,"SSLMode"
,"SSLPassword"
,"SSLRootCert"
,"StsEndpointUrl"
,"tcpKeepAlive"
,"UID"
,"User"
,"Username"
,"webIdentityToken"
)
));

RedshiftProperty(String name, String defaultValue, String description) {
this(name, defaultValue, description, false);
}
Expand Down Expand Up @@ -1276,4 +1361,15 @@ public String getSetString(Properties properties) {
}
return null;
}

/**
* Return the public property
*
* @return the value of a set property
*/
public static Set<String> getPublicProperties()
{
return publicProperties;
}
}

92 changes: 70 additions & 22 deletions src/main/java/com/amazon/redshift/logger/RedshiftLogger.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.Locale;

import com.amazon.redshift.RedshiftProperty;
import com.amazon.redshift.util.RedshiftProperties;
Expand All @@ -39,7 +41,7 @@ public class RedshiftLogger {

private static AtomicInteger connectionId = new AtomicInteger();

public RedshiftLogger(String fileName,
public RedshiftLogger(String fileName,
String logLevel,
boolean driver,
String maxLogFileSize,
Expand Down Expand Up @@ -163,14 +165,27 @@ else if (s.getMethodName().equals(functionName))
return Thread.currentThread().getStackTrace()[3];
}

public static String maskSecureInfoInUrl(String url) {
String[] tokens = {
RedshiftProperty.PWD.getName(),
RedshiftProperty.PASSWORD.getName(),
RedshiftProperty.IAM_ACCESS_KEY_ID.getName(),
RedshiftProperty.IAM_SECRET_ACCESS_KEY.getName(),
RedshiftProperty.IAM_SESSION_TOKEN.getName()
};
public static String maskSecureInfoInUrl(String url)
{
String[] tokens = {
RedshiftProperty.PWD.getName(),
RedshiftProperty.PASSWORD.getName(),
RedshiftProperty.IAM_ACCESS_KEY_ID.getName(),
RedshiftProperty.IAM_SECRET_ACCESS_KEY.getName(),
RedshiftProperty.IAM_SESSION_TOKEN.getName(),
RedshiftProperty.AUTH_PROFILE.getName(),
RedshiftProperty.SSL_KEY.getName(),
RedshiftProperty.SSL_PASSWORD.getName(),
RedshiftProperty.WEB_IDENTITY_TOKEN.getName(),
"Client_ID",
"Client_Secret",
"IdP_Tenant",
"Partner_SPID",
"Preferred_Role",
"Profile",
"roleArn",
};

String temp = maskSecureInfo(url, tokens, "[\\?;&]");

return temp;
Expand Down Expand Up @@ -207,28 +222,61 @@ public static String maskSecureInfo(String msg, String[] tokens, String tokenize

public static Properties maskSecureInfoInProps(Properties info) {

if(info == null) return info;
boolean secureInfoFound = false;

if(info == null) return null;

String[] propNames = {
RedshiftProperty.PWD.getName(),
RedshiftProperty.PASSWORD.getName(),
RedshiftProperty.IAM_ACCESS_KEY_ID.getName(),
RedshiftProperty.IAM_SECRET_ACCESS_KEY.getName(),
RedshiftProperty.IAM_SESSION_TOKEN.getName()
};
RedshiftProperty.IAM_SESSION_TOKEN.getName(),
RedshiftProperty.AUTH_PROFILE.getName(),
RedshiftProperty.SSL_KEY.getName(),
RedshiftProperty.SSL_PASSWORD.getName(),
RedshiftProperty.WEB_IDENTITY_TOKEN.getName(),
"Client_ID",
"Client_Secret",
"IdP_Tenant",
"Partner_SPID",
"Preferred_Role",
"Profile",
"roleArn",
};

Properties temp = new RedshiftProperties();
temp.putAll(info);
for(String propName : propNames) {
Object oldVal = replaceIgnoreCase(temp, propName, "***");
if(oldVal != null)
secureInfoFound = true;
Properties loggedProperties = new RedshiftProperties();
loggedProperties.putAll(info);
removeUnrecognizedPropertiesFromLogging(loggedProperties);

for(String propName : propNames)
{
replaceIgnoreCase(loggedProperties, propName, "***");
}

return (secureInfoFound) ? temp : info;
return loggedProperties;
}


/**
* fetches set of properties defined in the RedshiftProperty enum class and properties defined in public docs
* compares against given properties and removes unrecognized properties from logs
*/
public static void removeUnrecognizedPropertiesFromLogging(Properties loggedProperties)
{
Set<String> enumProperties = Arrays.stream(RedshiftProperty.values()).map(x -> x.getName().toLowerCase(Locale.US)).collect(Collectors.toSet());
Set<String> publicProperties = RedshiftProperty.getPublicProperties().stream().map(x -> x.toLowerCase(Locale.US)).collect(Collectors.toSet());

Set<String> allProperties = enumProperties.stream().collect(Collectors.toSet());
allProperties.addAll(publicProperties);

for (String givenProperty : loggedProperties.stringPropertyNames())
{
if (!allProperties.contains(givenProperty))
{
loggedProperties.remove(givenProperty);
}
}
}


public static String replaceIgnoreCase(Properties info, String key, String newVal) {
String value = info.getProperty(key);
if (null != value) {
Expand Down

0 comments on commit 037beb4

Please sign in to comment.