Skip to content

Commit

Permalink
Use LogLevel to limit RocksDB LOG file size
Browse files Browse the repository at this point in the history
- By default, the RocksDB is now only logging the config upon start up once with size ~700Bytes. 
- By default, the RocksDB only keeps ONE LOG file.
  • Loading branch information
yophilav authored Feb 22, 2020
1 parent 97a4d23 commit c984f63
Show file tree
Hide file tree
Showing 15 changed files with 81 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ public static class Constants

public const string StorageMaxTotalWalSize = "RocksDB_MaxTotalWalSize";

public const string StorageLogLevel = "Storage_LogLevel";

public const string WorkloadApiVersion = "2019-01-30";

public static class Labels
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ namespace Microsoft.Azure.Devices.Edge.Agent.Service
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Constants = Microsoft.Azure.Devices.Edge.Agent.Core.Constants;
using StorageLogLevel = Microsoft.Azure.Devices.Edge.Storage.StorageLogLevel;

public class Program
{
Expand Down Expand Up @@ -116,7 +117,8 @@ public static async Task<int> MainAsync(IConfiguration configuration)
int idleTimeoutSecs = configuration.GetValue(Constants.IdleTimeoutSecs, 300);
TimeSpan idleTimeout = TimeSpan.FromSeconds(idleTimeoutSecs);
ExperimentalFeatures experimentalFeatures = ExperimentalFeatures.Create(configuration.GetSection("experimentalFeatures"), logger);
Option<ulong> storageTotalMaxWalSize = GetStorageMaxTotalWalSizeIfExists(configuration);
Option<ulong> storageTotalMaxWalSize = GetStorageConfigIfExists<ulong>(Constants.StorageMaxTotalWalSize, configuration);
Option<StorageLogLevel> storageLogLevel = GetStorageConfigIfExists<StorageLogLevel>(Constants.StorageLogLevel, configuration);
metricsConfig = new MetricsConfig(experimentalFeatures.EnableMetrics, MetricsListenerConfig.Create(configuration));
string iothubHostname;
string deviceId;
Expand All @@ -130,7 +132,7 @@ public static async Task<int> MainAsync(IConfiguration configuration)
IotHubConnectionStringBuilder connectionStringParser = IotHubConnectionStringBuilder.Create(deviceConnectionString);
deviceId = connectionStringParser.DeviceId;
iothubHostname = connectionStringParser.HostName;
builder.RegisterModule(new AgentModule(maxRestartCount, intensiveCareTime, coolOffTimeUnitInSeconds, usePersistentStorage, storagePath, storageTotalMaxWalSize));
builder.RegisterModule(new AgentModule(maxRestartCount, intensiveCareTime, coolOffTimeUnitInSeconds, usePersistentStorage, storagePath, storageTotalMaxWalSize, storageLogLevel));
builder.RegisterModule(new DockerModule(deviceConnectionString, edgeDeviceHostName, dockerUri, dockerAuthConfig, upstreamProtocol, proxy, productInfo, closeOnIdleTimeout, idleTimeout, useServerHeartbeat));
break;

Expand All @@ -143,7 +145,7 @@ public static async Task<int> MainAsync(IConfiguration configuration)
string moduleGenerationId = configuration.GetValue<string>(Constants.EdgeletModuleGenerationIdVariableName);
apiVersion = configuration.GetValue<string>(Constants.EdgeletApiVersionVariableName);
TimeSpan performanceMetricsUpdateFrequency = configuration.GetValue("PerformanceMetricsUpdateFrequency", TimeSpan.FromSeconds(30));
builder.RegisterModule(new AgentModule(maxRestartCount, intensiveCareTime, coolOffTimeUnitInSeconds, usePersistentStorage, storagePath, Option.Some(new Uri(workloadUri)), Option.Some(apiVersion), moduleId, Option.Some(moduleGenerationId), storageTotalMaxWalSize));
builder.RegisterModule(new AgentModule(maxRestartCount, intensiveCareTime, coolOffTimeUnitInSeconds, usePersistentStorage, storagePath, Option.Some(new Uri(workloadUri)), Option.Some(apiVersion), moduleId, Option.Some(moduleGenerationId), storageTotalMaxWalSize, storageLogLevel));
builder.RegisterModule(new EdgeletModule(iothubHostname, edgeDeviceHostName, deviceId, new Uri(managementUri), new Uri(workloadUri), apiVersion, dockerAuthConfig, upstreamProtocol, proxy, productInfo, closeOnIdleTimeout, idleTimeout, performanceMetricsUpdateFrequency, useServerHeartbeat));

IEnumerable<X509Certificate2> trustBundle = await CertificateHelper.GetTrustBundleFromEdgelet(new Uri(workloadUri), apiVersion, Constants.WorkloadApiVersion, moduleId, moduleGenerationId);
Expand Down Expand Up @@ -320,19 +322,19 @@ static string GetLocalConfigFilePath(IConfiguration configuration, ILogger logge
return localConfigPath;
}

static Option<ulong> GetStorageMaxTotalWalSizeIfExists(IConfiguration configuration)
static Option<T> GetStorageConfigIfExists<T>(string fieldName, IConfiguration configuration)
{
ulong storageMaxTotalWalSize = 0;
T storageParamValue = default(T);
try
{
storageMaxTotalWalSize = configuration.GetValue<ulong>(Constants.StorageMaxTotalWalSize);
storageParamValue = configuration.GetValue<T>(fieldName);
}
catch
{
// ignored
}

return storageMaxTotalWalSize <= 0 ? Option.None<ulong>() : Option.Some(storageMaxTotalWalSize);
return EqualityComparer<T>.Default.Equals(storageParamValue, default(T)) ? Option.None<T>() : Option.Some(storageParamValue);
}

static void LogLogo(ILogger logger)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,10 @@ public class AgentModule : Module
readonly string moduleId;
readonly Option<string> moduleGenerationId;
readonly Option<ulong> storageTotalMaxWalSize;
readonly Option<StorageLogLevel> storageLogLevel;

public AgentModule(int maxRestartCount, TimeSpan intensiveCareTime, int coolOffTimeUnitInSeconds, bool usePersistentStorage, string storagePath, Option<ulong> storageTotalMaxWalSize)
: this(maxRestartCount, intensiveCareTime, coolOffTimeUnitInSeconds, usePersistentStorage, storagePath, Option.None<Uri>(), Option.None<string>(), Constants.EdgeAgentModuleIdentityName, Option.None<string>(), storageTotalMaxWalSize)
public AgentModule(int maxRestartCount, TimeSpan intensiveCareTime, int coolOffTimeUnitInSeconds, bool usePersistentStorage, string storagePath, Option<ulong> storageTotalMaxWalSize, Option<StorageLogLevel> storageLogLevel)
: this(maxRestartCount, intensiveCareTime, coolOffTimeUnitInSeconds, usePersistentStorage, storagePath, Option.None<Uri>(), Option.None<string>(), Constants.EdgeAgentModuleIdentityName, Option.None<string>(), storageTotalMaxWalSize, storageLogLevel)
{
}

Expand All @@ -47,7 +48,8 @@ public AgentModule(
Option<string> workloadApiVersion,
string moduleId,
Option<string> moduleGenerationId,
Option<ulong> storageTotalMaxWalSize)
Option<ulong> storageTotalMaxWalSize,
Option<StorageLogLevel> storageLogLevel)
{
this.maxRestartCount = maxRestartCount;
this.intensiveCareTime = intensiveCareTime;
Expand All @@ -59,6 +61,7 @@ public AgentModule(
this.moduleId = moduleId;
this.moduleGenerationId = moduleGenerationId;
this.storageTotalMaxWalSize = storageTotalMaxWalSize;
this.storageLogLevel = storageLogLevel;
}

static Dictionary<Type, IDictionary<string, Type>> DeploymentConfigTypeMapping
Expand Down Expand Up @@ -135,7 +138,7 @@ protected override void Load(ContainerBuilder builder)

// IRocksDbOptionsProvider
// For EdgeAgent, we don't need high performance from RocksDb, so always turn off optimizeForPerformance
builder.Register(c => new RocksDbOptionsProvider(c.Resolve<ISystemEnvironment>(), false, this.storageTotalMaxWalSize))
builder.Register(c => new RocksDbOptionsProvider(c.Resolve<ISystemEnvironment>(), false, this.storageTotalMaxWalSize, this.storageLogLevel))
.As<IRocksDbOptionsProvider>()
.SingleInstance();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public static class ConfigKey
public const string EdgeHubDevTrustBundleFile = "EdgeHubDevTrustBundleFile";
public const string EdgeHubClientCertAuthEnabled = "ClientCertAuthEnabled";
public const string StorageMaxTotalWalSize = "RocksDB_MaxTotalWalSize";
public const string StorageLogLevel = "Storage_LogLevel";
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ namespace Microsoft.Azure.Devices.Edge.Hub.Service
using Microsoft.Azure.Devices.ProtocolGateway.Instrumentation;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using StorageLogLevel = Microsoft.Azure.Devices.Edge.Storage.StorageLogLevel;

class DependencyManager : IDependencyManager
{
Expand Down Expand Up @@ -75,7 +76,7 @@ public void Register(ContainerBuilder builder)
});

bool optimizeForPerformance = this.configuration.GetValue("OptimizeForPerformance", true);
(bool isEnabled, bool usePersistentStorage, StoreAndForwardConfiguration config, string storagePath, Option<ulong> storageMaxTotalWalSize) storeAndForward = this.GetStoreAndForwardConfiguration();
(bool isEnabled, bool usePersistentStorage, StoreAndForwardConfiguration config, string storagePath, Option<ulong> storageMaxTotalWalSize, Option<StorageLogLevel> storageLogLevel) storeAndForward = this.GetStoreAndForwardConfiguration();

IConfiguration configuration = this.configuration.GetSection("experimentalFeatures");
ExperimentalFeatures experimentalFeatures = ExperimentalFeatures.Create(configuration);
Expand Down Expand Up @@ -104,7 +105,7 @@ void RegisterAmqpModule(ContainerBuilder builder)
builder.RegisterModule(new AmqpModule(amqpSettings["scheme"], amqpSettings.GetValue<ushort>("port"), this.serverCertificate, this.iotHubHostname, clientCertAuthEnabled));
}

void RegisterMqttModule(ContainerBuilder builder, (bool isEnabled, bool usePersistentStorage, StoreAndForwardConfiguration config, string storagePath, Option<ulong> storageMaxTotalWalSize) storeAndForward, bool optimizeForPerformance)
void RegisterMqttModule(ContainerBuilder builder, (bool isEnabled, bool usePersistentStorage, StoreAndForwardConfiguration config, string storagePath, Option<ulong> storageMaxTotalWalSize, Option<StorageLogLevel> storageLogLevel) storeAndForward, bool optimizeForPerformance)
{
var topics = new MessageAddressConversionConfiguration(
this.configuration.GetSection(Constants.TopicNameConversionSectionName + ":InboundTemplates").Get<List<string>>(),
Expand All @@ -118,7 +119,7 @@ void RegisterMqttModule(ContainerBuilder builder, (bool isEnabled, bool usePersi

void RegisterRoutingModule(
ContainerBuilder builder,
(bool isEnabled, bool usePersistentStorage, StoreAndForwardConfiguration config, string storagePath, Option<ulong> storageMaxTotalWalSize) storeAndForward,
(bool isEnabled, bool usePersistentStorage, StoreAndForwardConfiguration config, string storagePath, Option<ulong> storageMaxTotalWalSize, Option<StorageLogLevel> storageLogLevel) storeAndForward,
ExperimentalFeatures experimentalFeatures)
{
var routes = this.configuration.GetSection("routes").Get<Dictionary<string, string>>();
Expand Down Expand Up @@ -181,7 +182,7 @@ void RegisterRoutingModule(
void RegisterCommonModule(
ContainerBuilder builder,
bool optimizeForPerformance,
(bool isEnabled, bool usePersistentStorage, StoreAndForwardConfiguration config, string storagePath, Option<ulong> storageMaxTotalWalSize) storeAndForward,
(bool isEnabled, bool usePersistentStorage, StoreAndForwardConfiguration config, string storagePath, Option<ulong> storageMaxTotalWalSize, Option<StorageLogLevel> storageLogLevel) storeAndForward,
MetricsConfig metricsConfig)
{
bool cacheTokens = this.configuration.GetValue("CacheTokens", false);
Expand Down Expand Up @@ -221,7 +222,8 @@ void RegisterCommonModule(
this.trustBundle,
proxy,
metricsConfig,
storeAndForward.storageMaxTotalWalSize));
storeAndForward.storageMaxTotalWalSize,
storeAndForward.storageLogLevel));
}

static string GetProductInfo()
Expand All @@ -231,14 +233,15 @@ static string GetProductInfo()
return productInfo;
}

(bool isEnabled, bool usePersistentStorage, StoreAndForwardConfiguration config, string storagePath, Option<ulong> storageMaxTotalWalsize) GetStoreAndForwardConfiguration()
(bool isEnabled, bool usePersistentStorage, StoreAndForwardConfiguration config, string storagePath, Option<ulong> storageMaxTotalWalsize, Option<StorageLogLevel> storageLogLevel) GetStoreAndForwardConfiguration()
{
int defaultTtl = -1;
bool usePersistentStorage = this.configuration.GetValue<bool>("usePersistentStorage");
int timeToLiveSecs = defaultTtl;
string storagePath = this.GetStoragePath();
bool storeAndForwardEnabled = this.configuration.GetValue<bool>("storeAndForwardEnabled");
Option<ulong> storageMaxTotalWalSize = this.GetStorageMaxTotalWalSizeIfExists();
Option<ulong> storageMaxTotalWalSize = this.GetStorageConfigIfExists<ulong>(Constants.ConfigKey.StorageMaxTotalWalSize);
Option<StorageLogLevel> storageLogLevel = this.GetStorageConfigIfExists<StorageLogLevel>(Constants.ConfigKey.StorageLogLevel);

if (storeAndForwardEnabled)
{
Expand All @@ -247,22 +250,22 @@ static string GetProductInfo()
}

var storeAndForwardConfiguration = new StoreAndForwardConfiguration(timeToLiveSecs);
return (storeAndForwardEnabled, usePersistentStorage, storeAndForwardConfiguration, storagePath, storageMaxTotalWalSize);
return (storeAndForwardEnabled, usePersistentStorage, storeAndForwardConfiguration, storagePath, storageMaxTotalWalSize, storageLogLevel);
}

Option<ulong> GetStorageMaxTotalWalSizeIfExists()
Option<T> GetStorageConfigIfExists<T>(string fieldName)
{
ulong storageMaxTotalWalSize = 0;
T storageParamValue = default(T);
try
{
storageMaxTotalWalSize = this.configuration.GetValue<ulong>(Constants.ConfigKey.StorageMaxTotalWalSize);
storageParamValue = this.configuration.GetValue<T>(fieldName);
}
catch
{
// ignored
}

return storageMaxTotalWalSize <= 0 ? Option.None<ulong>() : Option.Some(storageMaxTotalWalSize);
return EqualityComparer<T>.Default.Equals(storageParamValue, default(T)) ? Option.None<T>() : Option.Some(storageParamValue);
}

// Note: Keep in sync with iotedge-check's edge-hub-storage-mounted-from-host check (edgelet/iotedge/src/check/checks/storage_mounted_from_host.rs)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public class CommonModule : Module
readonly string proxy;
readonly MetricsConfig metricsConfig;
readonly Option<ulong> storageMaxTotalWalSize;
readonly Option<StorageLogLevel> storageLogLevel;

public CommonModule(
string productInfo,
Expand All @@ -63,7 +64,8 @@ public CommonModule(
IList<X509Certificate2> trustBundle,
string proxy,
MetricsConfig metricsConfig,
Option<ulong> storageMaxTotalWalSize)
Option<ulong> storageMaxTotalWalSize,
Option<StorageLogLevel> storageLogLevel)
{
this.productInfo = productInfo;
this.iothubHostName = Preconditions.CheckNonWhiteSpace(iothubHostName, nameof(iothubHostName));
Expand All @@ -84,6 +86,7 @@ public CommonModule(
this.proxy = Preconditions.CheckNotNull(proxy, nameof(proxy));
this.metricsConfig = Preconditions.CheckNotNull(metricsConfig, nameof(metricsConfig));
this.storageMaxTotalWalSize = storageMaxTotalWalSize;
this.storageLogLevel = storageLogLevel;
}

protected override void Load(ContainerBuilder builder)
Expand Down Expand Up @@ -135,7 +138,7 @@ protected override void Load(ContainerBuilder builder)
.SingleInstance();

// DataBase options
builder.Register(c => new RocksDbOptionsProvider(c.Resolve<ISystemEnvironment>(), this.optimizeForPerformance, this.storageMaxTotalWalSize))
builder.Register(c => new RocksDbOptionsProvider(c.Resolve<ISystemEnvironment>(), this.optimizeForPerformance, this.storageMaxTotalWalSize, this.storageLogLevel))
.As<IRocksDbOptionsProvider>()
.SingleInstance();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ namespace Microsoft.Azure.Devices.Edge.Hub.E2E.Test
using Microsoft.Extensions.Logging;
using Moq;
using Constants = Microsoft.Azure.Devices.Edge.Hub.Service.Constants;
using StorageLogLevel = Microsoft.Azure.Devices.Edge.Storage.StorageLogLevel;

class DependencyManager : IDependencyManager
{
Expand Down Expand Up @@ -122,7 +123,8 @@ public void Register(ContainerBuilder builder)
this.trustBundle,
string.Empty,
metricsConfig,
Option.None<ulong>()));
Option.None<ulong>(),
Option.None<StorageLogLevel>()));

builder.RegisterModule(
new RoutingModule(
Expand Down
2 changes: 1 addition & 1 deletion edge-modules/TestAnalyzer/TestStatusStorage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public async Task InitAsync(string storagePath, ISystemEnvironment systemEnviron
{
var partitionsList = new List<string> { "messages", "directMethods", "twins" };
IDbStoreProvider dbStoreprovider = DbStoreProvider.Create(
new RocksDbOptionsProvider(systemEnvironment, optimizeForPerformance, Option.None<ulong>()),
new RocksDbOptionsProvider(systemEnvironment, optimizeForPerformance, Option.None<ulong>(), Option.None<StorageLogLevel>()),
this.GetStoragePath(storagePath),
partitionsList);

Expand Down
2 changes: 1 addition & 1 deletion edge-modules/TwinTester/TwinEventStorage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public void Init(string storagePath, ISystemEnvironment systemEnvironment, bool
{
var partitionsList = new List<string> { "desiredPropertyUpdated", "desiredPropertyReceived", "reportedPropertyUpdated" };
IDbStoreProvider dbStoreprovider = DbStoreProvider.Create(
new RocksDbOptionsProvider(systemEnvironment, optimizeForPerformance, Option.None<ulong>()),
new RocksDbOptionsProvider(systemEnvironment, optimizeForPerformance, Option.None<ulong>(), Option.None<StorageLogLevel>()),
this.GetStoragePath(storagePath),
partitionsList);

Expand Down
Loading

0 comments on commit c984f63

Please sign in to comment.