Skip to content

Commit d33714f

Browse files
authored
summary: Add new configuration options for logging. (#1880) (#2264)
feat: Add new configuration options for logging to control log file size, log retention and log rollover strategy. Refer to our [log configuration documentation](https://docs.newrelic.com/docs/apm/agents/net-agent/configuration/net-agent-configuration/#log) for details. (#1880) (#2264)
1 parent d4372ca commit d33714f

File tree

6 files changed

+387
-74
lines changed

6 files changed

+387
-74
lines changed

src/Agent/NewRelic/Agent/Core/Config/Configuration.cs

+76-11
Original file line numberDiff line numberDiff line change
@@ -1284,10 +1284,11 @@ public virtual configurationApplication Clone()
12841284
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:newrelic-config")]
12851285
public partial class configurationLog
12861286
{
1287-
private bool enabledField;
12881287

12891288
private string levelField;
12901289

1290+
private bool enabledField;
1291+
12911292
private string directoryField;
12921293

12931294
private string fileNameField;
@@ -1296,15 +1297,24 @@ public partial class configurationLog
12961297

12971298
private bool auditLogField;
12981299

1300+
private configurationLogLogRollingStrategy logRollingStrategyField;
1301+
1302+
private int maxLogFileSizeMBField;
1303+
1304+
private int maxLogFilesField;
1305+
12991306
/// <summary>
13001307
/// configurationLog class constructor
13011308
/// </summary>
13021309
public configurationLog()
13031310
{
1304-
this.enabledField = true;
13051311
this.levelField = "info";
1312+
this.enabledField = true;
13061313
this.consoleField = false;
13071314
this.auditLogField = false;
1315+
this.logRollingStrategyField = configurationLogLogRollingStrategy.size;
1316+
this.maxLogFileSizeMBField = 50;
1317+
this.maxLogFilesField = 4;
13081318
}
13091319

13101320
[System.Xml.Serialization.XmlAttributeAttribute()]
@@ -1321,6 +1331,20 @@ public string level
13211331
}
13221332
}
13231333

1334+
[System.Xml.Serialization.XmlAttributeAttribute()]
1335+
[System.ComponentModel.DefaultValueAttribute(true)]
1336+
public bool enabled
1337+
{
1338+
get
1339+
{
1340+
return this.enabledField;
1341+
}
1342+
set
1343+
{
1344+
this.enabledField = value;
1345+
}
1346+
}
1347+
13241348
[System.Xml.Serialization.XmlAttributeAttribute()]
13251349
public string directory
13261350
{
@@ -1360,32 +1384,60 @@ public bool console
13601384
this.consoleField = value;
13611385
}
13621386
}
1363-
1387+
13641388
[System.Xml.Serialization.XmlAttributeAttribute()]
1365-
[System.ComponentModel.DefaultValueAttribute(true)]
1366-
public bool enabled
1389+
[System.ComponentModel.DefaultValueAttribute(false)]
1390+
public bool auditLog
13671391
{
13681392
get
13691393
{
1370-
return this.enabledField;
1394+
return this.auditLogField;
13711395
}
13721396
set
13731397
{
1374-
this.enabledField = value;
1398+
this.auditLogField = value;
13751399
}
13761400
}
13771401

13781402
[System.Xml.Serialization.XmlAttributeAttribute()]
1379-
[System.ComponentModel.DefaultValueAttribute(false)]
1380-
public bool auditLog
1403+
[System.ComponentModel.DefaultValueAttribute(configurationLogLogRollingStrategy.size)]
1404+
public configurationLogLogRollingStrategy logRollingStrategy
13811405
{
13821406
get
13831407
{
1384-
return this.auditLogField;
1408+
return this.logRollingStrategyField;
13851409
}
13861410
set
13871411
{
1388-
this.auditLogField = value;
1412+
this.logRollingStrategyField = value;
1413+
}
1414+
}
1415+
1416+
[System.Xml.Serialization.XmlAttributeAttribute()]
1417+
[System.ComponentModel.DefaultValueAttribute(50)]
1418+
public int maxLogFileSizeMB
1419+
{
1420+
get
1421+
{
1422+
return this.maxLogFileSizeMBField;
1423+
}
1424+
set
1425+
{
1426+
this.maxLogFileSizeMBField = value;
1427+
}
1428+
}
1429+
1430+
[System.Xml.Serialization.XmlAttributeAttribute()]
1431+
[System.ComponentModel.DefaultValueAttribute(4)]
1432+
public int maxLogFiles
1433+
{
1434+
get
1435+
{
1436+
return this.maxLogFilesField;
1437+
}
1438+
set
1439+
{
1440+
this.maxLogFilesField = value;
13891441
}
13901442
}
13911443

@@ -1400,6 +1452,19 @@ public virtual configurationLog Clone()
14001452
#endregion
14011453
}
14021454

1455+
[System.CodeDom.Compiler.GeneratedCodeAttribute("Xsd2Code", "3.6.0.20097")]
1456+
[System.SerializableAttribute()]
1457+
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:newrelic-config")]
1458+
public enum configurationLogLogRollingStrategy
1459+
{
1460+
1461+
/// <remarks/>
1462+
size,
1463+
1464+
/// <remarks/>
1465+
day,
1466+
}
1467+
14031468
[System.CodeDom.Compiler.GeneratedCodeAttribute("Xsd2Code", "3.6.0.20097")]
14041469
[System.SerializableAttribute()]
14051470
[System.ComponentModel.DesignerCategoryAttribute("code")]

src/Agent/NewRelic/Agent/Core/Config/Configuration.xsd

+43-1
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@
320320
</xs:documentation>
321321
</xs:annotation>
322322
</xs:attribute>
323-
323+
324324
<xs:attribute name="directory" type="xs:string" use="optional">
325325
<xs:annotation>
326326
<xs:documentation>
@@ -355,6 +355,48 @@
355355
</xs:annotation>
356356
</xs:attribute>
357357

358+
<xs:attribute name="logRollingStrategy" default="size" use="optional" >
359+
<xs:annotation>
360+
<xs:documentation>
361+
The strategy to use for rolling over the Agent log file. Default is size.
362+
</xs:documentation>
363+
</xs:annotation>
364+
<xs:simpleType>
365+
<xs:restriction base="xs:string">
366+
<xs:enumeration value="size">
367+
<xs:annotation>
368+
<xs:documentation>
369+
The Agent log file will be rolled over when it reaches the size specified in maxLogFileSizeMB.
370+
</xs:documentation>
371+
</xs:annotation>
372+
</xs:enumeration>
373+
<xs:enumeration value="day">
374+
<xs:annotation>
375+
<xs:documentation>
376+
The Agent log file will be rolled over once each day.
377+
</xs:documentation>
378+
</xs:annotation>
379+
</xs:enumeration>
380+
</xs:restriction>
381+
</xs:simpleType>
382+
</xs:attribute>
383+
384+
<xs:attribute name="maxLogFileSizeMB" type="xs:int" default="50" use="optional">
385+
<xs:annotation>
386+
<xs:documentation>
387+
The maximum size of the Agent log file in megabytes before it is rolled over. Default is 50MB. If this is set to 0, no size limit will be enforced. Only used if logRollingStrategy is set to "size".
388+
</xs:documentation>
389+
</xs:annotation>
390+
</xs:attribute>
391+
392+
<xs:attribute name="maxLogFiles" type="xs:int" default="4" use="optional">
393+
<xs:annotation>
394+
<xs:documentation>
395+
The maximum number of Agent log files to keep. Defaults to 4. If this is set to 0, then all log files will be kept.
396+
</xs:documentation>
397+
</xs:annotation>
398+
</xs:attribute>
399+
358400
</xs:complexType>
359401
</xs:element>
360402

src/Agent/NewRelic/Agent/Core/Config/ConfigurationLoader.cs

+92-54
Original file line numberDiff line numberDiff line change
@@ -147,21 +147,21 @@ private static string TryGetAgentConfigFileFromAppConfig()
147147

148148
#if NETSTANDARD2_0
149149

150-
try
151-
{
152-
var fileName = AppSettingsConfigResolveWhenUsed.GetAppSetting(Constants.AppSettingsConfigFile);
153-
if (!File.Exists(fileName))
154-
{
155-
return null;
156-
}
157-
158-
Log.Info("Configuration file found in path pointed to by {0} appSetting: {1}", Constants.AppSettingsConfigFile, fileName);
159-
return fileName;
160-
}
161-
catch (Exception)
162-
{
163-
return null;
164-
}
150+
try
151+
{
152+
var fileName = AppSettingsConfigResolveWhenUsed.GetAppSetting(Constants.AppSettingsConfigFile);
153+
if (!File.Exists(fileName))
154+
{
155+
return null;
156+
}
157+
158+
Log.Info("Configuration file found in path pointed to by {0} appSetting: {1}", Constants.AppSettingsConfigFile, fileName);
159+
return fileName;
160+
}
161+
catch (Exception)
162+
{
163+
return null;
164+
}
165165

166166
#else
167167
try
@@ -185,36 +185,36 @@ private static string TryGetAgentConfigFileFromAppConfig()
185185
private static string TryGetAgentConfigFileFromAppRoot()
186186
{
187187
#if NETSTANDARD2_0
188-
try
189-
{
190-
var filename = string.Empty;
191-
192-
var entryAssembly = Assembly.GetEntryAssembly();
193-
if (entryAssembly != null)
194-
{
195-
var directory = Path.GetDirectoryName(entryAssembly.Location);
196-
filename = Path.Combine(directory, NewRelicConfigFileName);
197-
if (File.Exists(filename))
198-
{
199-
Log.Info("Configuration file found in app/web root directory: {0}", filename);
200-
return filename;
201-
}
202-
}
203-
204-
var currentDirectory = Directory.GetCurrentDirectory();
205-
filename = Path.Combine(currentDirectory, NewRelicConfigFileName);
206-
if (File.Exists(filename))
207-
{
208-
Log.Info("Configuration file found in app/web root directory: {0}", filename);
209-
return filename;
210-
}
211-
212-
return null;
213-
}
214-
catch (Exception)
215-
{
216-
return null;
217-
}
188+
try
189+
{
190+
var filename = string.Empty;
191+
192+
var entryAssembly = Assembly.GetEntryAssembly();
193+
if (entryAssembly != null)
194+
{
195+
var directory = Path.GetDirectoryName(entryAssembly.Location);
196+
filename = Path.Combine(directory, NewRelicConfigFileName);
197+
if (File.Exists(filename))
198+
{
199+
Log.Info("Configuration file found in app/web root directory: {0}", filename);
200+
return filename;
201+
}
202+
}
203+
204+
var currentDirectory = Directory.GetCurrentDirectory();
205+
filename = Path.Combine(currentDirectory, NewRelicConfigFileName);
206+
if (File.Exists(filename))
207+
{
208+
Log.Info("Configuration file found in app/web root directory: {0}", filename);
209+
return filename;
210+
}
211+
212+
return null;
213+
}
214+
catch (Exception)
215+
{
216+
return null;
217+
}
218218
#else
219219
try
220220
{
@@ -577,14 +577,14 @@ private string GetLogFileName()
577577
}
578578

579579
#if NETSTANDARD2_0
580-
try
581-
{
582-
name = AppDomain.CurrentDomain.FriendlyName;
583-
}
584-
catch (Exception)
585-
{
586-
name = _processStatic.GetCurrentProcess().ProcessName;
587-
}
580+
try
581+
{
582+
name = AppDomain.CurrentDomain.FriendlyName;
583+
}
584+
catch (Exception)
585+
{
586+
name = _processStatic.GetCurrentProcess().ProcessName;
587+
}
588588
#else
589589
if (HttpRuntime.AppDomainAppId != null)
590590
{
@@ -626,6 +626,29 @@ private bool GetOverride(string name, bool fallback)
626626
return fallback;
627627
}
628628

629+
private string GetOverride(string name, string fallback)
630+
{
631+
var val = ConfigurationLoader.GetEnvironmentVar(name);
632+
633+
if (val != null)
634+
{
635+
return val;
636+
}
637+
638+
return fallback;
639+
}
640+
private int GetOverride(string name, int fallback)
641+
{
642+
var val = ConfigurationLoader.GetEnvironmentVar(name);
643+
644+
if (val != null && int.TryParse(val, out var parsedValue))
645+
{
646+
return parsedValue;
647+
}
648+
649+
return fallback;
650+
}
651+
629652
public bool Console
630653
{
631654
get
@@ -650,6 +673,21 @@ public bool IsAuditLogEnabled
650673
}
651674
}
652675

676+
public int MaxLogFileSizeMB => GetOverride("NEW_RELIC_LOG_MAX_FILE_SIZE_MB", maxLogFileSizeMB);
677+
public int MaxLogFiles => GetOverride("NEW_RELIC_LOG_MAX_FILES", maxLogFiles);
678+
public LogRollingStrategy LogRollingStrategy
679+
{
680+
get
681+
{
682+
var strategy = GetOverride("NEW_RELIC_LOG_ROLLING_STRATEGY", logRollingStrategy.ToString());
683+
if (Enum.TryParse(strategy, true, out LogRollingStrategy result))
684+
{
685+
return result;
686+
}
687+
688+
throw new ConfigurationLoaderException($"Invalid value for logRollingStrategy or NEW_RELIC_LOG_ROLLING_STRATEGY: {strategy}");
689+
}
690+
}
653691
}
654692

655693
// The configuration class is partial. Part of it is implemented here,
@@ -697,7 +735,7 @@ public configuration Initialize(string xml, string provenance)
697735
}
698736

699737
/// <summary>
700-
/// Thrown when there is soime problem loading the configuration.
738+
/// Thrown when there is some problem loading the configuration.
701739
/// </summary>
702740
public class ConfigurationLoaderException : Exception
703741
{

0 commit comments

Comments
 (0)