|
1 | 1 | package datadog.trace.api; |
2 | 2 |
|
| 3 | +import java.io.File; |
| 4 | +import java.io.FileNotFoundException; |
| 5 | +import java.io.FileReader; |
| 6 | +import java.io.IOException; |
3 | 7 | import java.net.InetAddress; |
4 | 8 | import java.net.UnknownHostException; |
5 | 9 | import java.util.Arrays; |
@@ -35,6 +39,7 @@ public class Config { |
35 | 39 |
|
36 | 40 | private static final Pattern ENV_REPLACEMENT = Pattern.compile("[^a-zA-Z0-9_]"); |
37 | 41 |
|
| 42 | + public static final String CONFIGURATION_FILE = "trace.config"; |
38 | 43 | public static final String SERVICE_NAME = "service.name"; |
39 | 44 | public static final String SERVICE = "service"; |
40 | 45 | public static final String TRACE_ENABLED = "trace.enabled"; |
@@ -186,6 +191,7 @@ public enum PropagationStyle { |
186 | 191 | @Getter private final List<String> traceExecutors; |
187 | 192 |
|
188 | 193 | @Getter private final boolean traceAnalyticsEnabled; |
| 194 | + private static final Properties propertiesFromConfigFile = loadConfigurationFile(); |
189 | 195 |
|
190 | 196 | // Read order: System Properties -> Env Variables, [-> default value] |
191 | 197 | // Visible for testing |
@@ -555,19 +561,36 @@ public static boolean traceAnalyticsIntegrationEnabled( |
555 | 561 | /** |
556 | 562 | * Helper method that takes the name, adds a "dd." prefix then checks for System Properties of |
557 | 563 | * that name. If none found, the name is converted to an Environment Variable and used to check |
558 | | - * the env. If setting not configured in either location, defaultValue is returned. |
| 564 | + * the env. If none of the above returns a value, then an optional properties file if checked. If |
| 565 | + * setting is not configured in either location, <code>defaultValue</code> is returned. |
559 | 566 | * |
560 | 567 | * @param name |
561 | 568 | * @param defaultValue |
562 | 569 | * @return |
563 | 570 | * @deprecated This method should only be used internally. Use the explicit getter instead. |
564 | 571 | */ |
565 | 572 | public static String getSettingFromEnvironment(final String name, final String defaultValue) { |
566 | | - final String completeName = PREFIX + name; |
567 | | - final String value = |
568 | | - System.getProperties() |
569 | | - .getProperty(completeName, System.getenv(propertyToEnvironmentName(completeName))); |
570 | | - return value == null ? defaultValue : value; |
| 573 | + String value; |
| 574 | + |
| 575 | + // System properties and properties provided from command line have the highest precedence |
| 576 | + value = System.getProperties().getProperty(propertyNameToSystemPropertyName(name)); |
| 577 | + if (null != value) { |
| 578 | + return value; |
| 579 | + } |
| 580 | + |
| 581 | + // If value not provided from system properties, looking at env variables |
| 582 | + value = System.getenv(propertyNameToEnvironmentVariableName(name)); |
| 583 | + if (null != value) { |
| 584 | + return value; |
| 585 | + } |
| 586 | + |
| 587 | + // If value is not defined yet, we look at properties optionally defined in a properties file |
| 588 | + value = propertiesFromConfigFile.getProperty(propertyNameToSystemPropertyName(name)); |
| 589 | + if (null != value) { |
| 590 | + return value; |
| 591 | + } |
| 592 | + |
| 593 | + return defaultValue; |
571 | 594 | } |
572 | 595 |
|
573 | 596 | /** @deprecated This method should only be used internally. Use the explicit getter instead. */ |
@@ -663,8 +686,28 @@ private Set<Integer> getIntegerRangeSettingFromEnvironment( |
663 | 686 | } |
664 | 687 | } |
665 | 688 |
|
666 | | - private static String propertyToEnvironmentName(final String name) { |
667 | | - return ENV_REPLACEMENT.matcher(name.toUpperCase()).replaceAll("_"); |
| 689 | + /** |
| 690 | + * Converts the property name, e.g. 'service.name' into a public environment variable name, e.g. |
| 691 | + * `DD_SERVICE_NAME`. |
| 692 | + * |
| 693 | + * @param setting The setting name, e.g. `service.name` |
| 694 | + * @return The public facing environment variable name |
| 695 | + */ |
| 696 | + private static String propertyNameToEnvironmentVariableName(final String setting) { |
| 697 | + return ENV_REPLACEMENT |
| 698 | + .matcher(propertyNameToSystemPropertyName(setting).toUpperCase()) |
| 699 | + .replaceAll("_"); |
| 700 | + } |
| 701 | + |
| 702 | + /** |
| 703 | + * Converts the property name, e.g. 'service.name' into a public system property name, e.g. |
| 704 | + * `dd.service.name`. |
| 705 | + * |
| 706 | + * @param setting The setting name, e.g. `service.name` |
| 707 | + * @return The public facing system property name |
| 708 | + */ |
| 709 | + private static String propertyNameToSystemPropertyName(String setting) { |
| 710 | + return PREFIX + setting; |
668 | 711 | } |
669 | 712 |
|
670 | 713 | private static Map<String, String> getPropertyMapValue( |
@@ -819,6 +862,44 @@ private static <V extends Enum<V>> Set<V> convertStringSetToEnumSet( |
819 | 862 | return Collections.unmodifiableSet(result); |
820 | 863 | } |
821 | 864 |
|
| 865 | + /** |
| 866 | + * Loads the optional configuration properties file into the global {@link Properties} object. |
| 867 | + * |
| 868 | + * @return The {@link Properties} object. the returned instance might be empty of file does not |
| 869 | + * exist or if it is in a wrong format. |
| 870 | + */ |
| 871 | + private static Properties loadConfigurationFile() { |
| 872 | + Properties properties = new Properties(); |
| 873 | + |
| 874 | + String configurationFilePath = |
| 875 | + System.getProperty(propertyNameToSystemPropertyName(CONFIGURATION_FILE)); |
| 876 | + if (null == configurationFilePath) { |
| 877 | + configurationFilePath = |
| 878 | + System.getenv(propertyNameToEnvironmentVariableName(CONFIGURATION_FILE)); |
| 879 | + } |
| 880 | + if (null == configurationFilePath) { |
| 881 | + return properties; |
| 882 | + } |
| 883 | + |
| 884 | + // Configuration properties file is optional |
| 885 | + File configurationFile = new File(configurationFilePath); |
| 886 | + if (!configurationFile.exists()) { |
| 887 | + return properties; |
| 888 | + } |
| 889 | + |
| 890 | + try { |
| 891 | + FileReader fileReader = new FileReader(configurationFile); |
| 892 | + properties.load(fileReader); |
| 893 | + } catch (FileNotFoundException fnf) { |
| 894 | + log.error("Configuration file '{}' not found.", configurationFilePath); |
| 895 | + } catch (IOException e) { |
| 896 | + log.error( |
| 897 | + "Configuration file '{}' cannot be accessed or correctly parsed.", configurationFilePath); |
| 898 | + } |
| 899 | + |
| 900 | + return properties; |
| 901 | + } |
| 902 | + |
822 | 903 | /** |
823 | 904 | * Returns the detected hostname. This operation is time consuming so if the usage changes and |
824 | 905 | * this method will be called several times then we should implement some sort of caching. |
|
0 commit comments