将自定义字段添加到站点的日志文件 <add>
概述
<customField>
元素下的 <add>
元素控制站点 W3C 日志自定义字段的配置设置。
除了标准记录集之外,IIS 8.5 还支持记录自定义字段。 这些自定义字段可包括来自请求头、响应头或服务器变量的数据。 若要记录这些字段,只需设置配置属性,而无需创建自定义记录模块。 此功能只能在站点级别使用。 日志文件格式必须是 W3C 才能添加自定义字段。
将自定义字段添加到标准集后,文件名后将附加“_x”,以显示日志文件包含自定义字段。 自定义字段中添加的数据总量不能超过 65,536 字节。 如果自定义记录的数据超过该数量,IIS 将截断数据。 任何一个自定义字段中可添加到日志文件的最大数据量由 maxCustomFieldLength 属性指定。
若要配置自定义字段,请指定字段名称、源名称和源类型。 可以将自定义信息放入服务器变量中,并记录服务器变量。 选择源类型后,可以选择现有源名称或输入新的源名称。
使用自定义字段可以收集有关进程的有用数据并将其聚合到 IIS 日志中。 在包含负载均衡器的系统中,可能会在日志中看到负载均衡器的 IP 地址,但可以在自定义字段中记录 X-Forwarded-For 头,以便了解原始请求者。 可以记录进程运行时间,查看进程在一天内重启了多少次。 如果内存开始过度使用,就可以确定内存是何时开始消耗的、请求的是哪个页面,以及客户端的 ID 是什么(如果他们在恶意操作,这一点将特别有用)。
兼容性
版本 | 说明 |
---|---|
IIS 10.0 | <add> 元素在 IIS 10.0 中未进行修改。 |
IIS 8.5 | <add> 元素是在 IIS 8.5 中引入的。 |
IIS 8.0 | 空值 |
IIS 7.5 | 空值 |
IIS 7.0 | 空值 |
IIS 6.0 | 空值 |
安装
<add>
元素包含在 IIS 8.5 及更高版本的默认安装中。
操作方式
如何添加自定义字段
打开 Internet Information Services (IIS) 管理器:
如果使用的是 Windows Server 2012 R2:
- 在任务栏上,单击“服务器管理器”,单击“工具”,然后单击“Internet Information Services (IIS)管理器”。
如果使用的是 Windows 8.1:
- 按住 Windows 键,按字母 X,然后单击“控制面板”。
- 单击“管理工具”,然后双击“Internet 信息服务(IIS)管理器”。
在“连接”窗格中,展开服务器,展开“站点”,然后选择一个站点。
双击“日志记录”。
在“日志记录”主页中,对于“格式”,选择“W3C”。
单击“选择字段”。
在“W3C 日志记录字段”对话框中,单击“添加字段”。
在“添加自定义字段”对话框中,在“字段名”中输入名称,并为“源类型”选择下列名称之一:“请求头”、“响应头”或“服务器变量”。
在“源”中,从列表中选择源,或输入自定义源的名称。
单击“确定”,然后再次单击“确定”。
在“操作”窗格中,单击“应用”。
如何配置最大自定义字段长度
打开 Internet Information Services (IIS) 管理器:
如果使用的是 Windows Server 2012 R2:
- 在任务栏上,单击“服务器管理器”,单击“工具”,然后单击“Internet Information Services (IIS)管理器”。
如果使用的是 Windows 8.1:
- 按住 Windows 键,按字母 X,然后单击“控制面板”。
- 单击“管理工具”,然后双击“Internet 信息服务(IIS)管理器”。
在“连接”窗格中,选择服务器,然后在“管理”区域中,双击“配置编辑器”。
在“配置编辑器”中,对于“部分”,选择“system.applicationHost”,然后选择“站点”。
单击“(集合)”,然后单击省略号。
选择站点,展开“logFile”,展开“customFields”,然后单击“maxCustomFieldLength”。
对于 maxCustomFieldLength,输入任何一个自定义字段中可添加到日志文件的最大数据量(以字节为单位)。
关闭“集合编辑器”,然后在“操作”窗格中,单击“应用”。
配置
<add>
元素在站点级别配置。
特性
属性 | 说明 |
---|---|
logFieldName |
必需的字符串属性。 指定要添加到日志文件的自定义字段。 字段名称不能包含空格。 |
sourceName |
必需的字符串属性。 指定包含要添加到日志自定义字段的值的 HTTP 头或服务器变量的名称。 名称可以是自定义源字符串。 |
sourceType |
必需 enum 属性。 要添加到日志自定义字段的数据的源类型。 可以是 RequestHeader(值 = 0)、ResponseHeader(值 = 1)或 ServerVariable(值 = 2)。 |
子元素
无。
配置示例
以下配置示例使用 customFields
元素及其 add
子元素来指定默认网站的日志自定义字段设置。
<sites>
<site name="Default Web Site" id="1">
<logFile logFormat="W3C" logTargetW3C="File, ETW">
<customFields maxCustomFieldLength="4095">
<clear />
<add logFieldName="X-Forwarded-For" sourceName="X_FORWARDED_FOR"
sourceType="RequestHeader" />
</customFields>
</logFile>
</site>
</sites>
代码示例
以下示例为站点的 W3C 日志配置自定义字段。
AppCmd.exe
appcmd.exe set config -section:system.applicationHost/sites /+"[name='ContosoSite'].logFile.customFields.[logFieldName='ContosoField',sourceName='ContosoSource',sourceType='ServerVariable']" /commit:apphost
注意
使用 AppCmd.exe 配置这些设置时,必须确保将 commit 参数设置为 apphost
。 这会将配置设置提交到 ApplicationHost.config 文件中的相应位置部分。
C#
using System;
using System.Text;
using Microsoft.Web.Administration;
internal static class Sample
{
private static void Main()
{
using(ServerManager serverManager = new ServerManager())
{
Configuration config = serverManager.GetApplicationHostConfiguration();
ConfigurationSection sitesSection = config.GetSection("system.applicationHost/sites");
ConfigurationElementCollection sitesCollection = sitesSection.GetCollection();
ConfigurationElement siteElement = FindElement(sitesCollection, "site", "name", @"ContosoSite");
if (siteElement == null) throw new InvalidOperationException("Element not found!");
ConfigurationElement logFileElement = siteElement.GetChildElement("logFile");
ConfigurationElement customFieldsElement = logFileElement.GetChildElement("customFields");
ConfigurationElementCollection customFieldsCollection = customFieldsElement.GetCollection();
ConfigurationElement addElement = customFieldsCollection.CreateElement("add");
addElement["logFieldName"] = @"ContosoField";
addElement["sourceName"] = @"ContosoSource";
addElement["sourceType"] = @"ServerVariable";
customFieldsCollection.Add(addElement);
serverManager.CommitChanges();
}
}
private static ConfigurationElement FindElement(ConfigurationElementCollection collection, string elementTagName, params string[] keyValues)
{
foreach (ConfigurationElement element in collection)
{
if (String.Equals(element.ElementTagName, elementTagName, StringComparison.OrdinalIgnoreCase))
{
bool matches = true;
for (int i = 0; i < keyValues.Length; i += 2)
{
object o = element.GetAttributeValue(keyValues[i]);
string value = null;
if (o != null)
{
value = o.ToString();
}
if (!String.Equals(value, keyValues[i + 1], StringComparison.OrdinalIgnoreCase))
{
matches = false;
break;
}
}
if (matches)
{
return element;
}
}
}
return null;
}
}
VB.NET
Imports System
Imports System.Text
Imports Microsoft.Web.Administration
Module Sample
Sub Main()
Dim serverManager As ServerManager = New ServerManager
Dim config As Configuration = serverManager.GetApplicationHostConfiguration
Dim sitesSection As ConfigurationSection = config.GetSection("system.applicationHost/sites")
Dim sitesCollection As ConfigurationElementCollection = sitesSection.GetCollection
Dim siteElement As ConfigurationElement = FindElement(sitesCollection, "site", "name", "ContosoSite")
If (siteElement Is Nothing) Then
Throw New InvalidOperationException("Element not found!")
End If
Dim logFileElement As ConfigurationElement = siteElement.GetChildElement("logFile")
Dim customFieldsElement As ConfigurationElement = logFileElement.GetChildElement("customFields")
Dim customFieldsCollection As ConfigurationElementCollection = customFieldsElement.GetCollection
Dim addElement As ConfigurationElement = customFieldsCollection.CreateElement("add")
addElement("logFieldName") = "ContosoField"
addElement("sourceName") = "ContosoSource"
addElement("sourceType") = "ServerVariable"
customFieldsCollection.Add(addElement)
serverManager.CommitChanges
End Sub
Private Function FindElement(ByVal collection As ConfigurationElementCollection, ByVal elementTagName As String, ByVal ParamArray keyValues() As String) As ConfigurationElement
For Each element As ConfigurationElement In collection
If String.Equals(element.ElementTagName, elementTagName, StringComparison.OrdinalIgnoreCase) Then
Dim matches As Boolean = True
Dim i As Integer
For i = 0 To keyValues.Length - 1 Step 2
Dim o As Object = element.GetAttributeValue(keyValues(i))
Dim value As String = Nothing
If (Not (o) Is Nothing) Then
value = o.ToString
End If
If Not String.Equals(value, keyValues((i + 1)), StringComparison.OrdinalIgnoreCase) Then
matches = False
Exit For
End If
Next
If matches Then
Return element
End If
End If
Next
Return Nothing
End Function
End Module
JavaScript
var adminManager = new ActiveXObject('Microsoft.ApplicationHost.WritableAdminManager');
adminManager.CommitPath = "MACHINE/WEBROOT/APPHOST";
var sitesSection = adminManager.GetAdminSection("system.applicationHost/sites", "MACHINE/WEBROOT/APPHOST");
var sitesCollection = sitesSection.Collection;
var siteElementPos = FindElement(sitesCollection, "site", ["name", "ContosoSite"]);
if (siteElementPos == -1) throw "Element not found!";
var siteElement = sitesCollection.Item(siteElementPos);
var logFileElement = siteElement.ChildElements.Item("logFile");
var customFieldsElement = logFileElement.ChildElements.Item("customFields");
var customFieldsCollection = customFieldsElement.Collection;
var addElement = customFieldsCollection.CreateNewElement("add");
addElement.Properties.Item("logFieldName").Value = "ContosoField";
addElement.Properties.Item("sourceName").Value = "ContosoSource";
addElement.Properties.Item("sourceType").Value = "ServerVariable";
customFieldsCollection.AddElement(addElement);
adminManager.CommitChanges();
function FindElement(collection, elementTagName, valuesToMatch) {
for (var i = 0; i < collection.Count; i++) {
var element = collection.Item(i);
if (element.Name == elementTagName) {
var matches = true;
for (var iVal = 0; iVal < valuesToMatch.length; iVal += 2) {
var property = element.GetPropertyByName(valuesToMatch[iVal]);
var value = property.Value;
if (value != null) {
value = value.toString();
}
if (value != valuesToMatch[iVal + 1]) {
matches = false;
break;
}
}
if (matches) {
return i;
}
}
}
return -1;
}
VBScript
Set adminManager = CreateObject("Microsoft.ApplicationHost.WritableAdminManager")
adminManager.CommitPath = "MACHINE/WEBROOT/APPHOST"
Set sitesSection = adminManager.GetAdminSection("system.applicationHost/sites", "MACHINE/WEBROOT/APPHOST")
Set sitesCollection = sitesSection.Collection
siteElementPos = FindElement(sitesCollection, "site", array ("name", "ContosoSite"))
if (siteElementPos = -1) THEN throw "Element not found!"
Set siteElement = sitesCollection.Item(siteElementPos)
Set logFileElement = siteElement.ChildElements.Item("logFile")
Set customFieldsElement = logFileElement.ChildElements.Item("customFields")
Set customFieldsCollection = customFieldsElement.Collection
Set addElement = customFieldsCollection.CreateNewElement("add")
addElement.Properties.Item("logFieldName").Value = "ContosoField"
addElement.Properties.Item("sourceName").Value = "ContosoSource"
addElement.Properties.Item("sourceType").Value = "ServerVariable"
customFieldsCollection.AddElement(addElement)
adminManager.CommitChanges()
Function FindElement(collection, elementTagName, valuesToMatch)
For i = 0 To CInt(collection.Count) - 1
Set element = collection.Item(i)
If element.Name = elementTagName Then
matches = True
For iVal = 0 To UBound(valuesToMatch) Step 2
Set property = element.GetPropertyByName(valuesToMatch(iVal))
value = property.Value
If Not IsNull(value) Then
value = CStr(value)
End If
If Not value = CStr(valuesToMatch(iVal + 1)) Then
matches = False
Exit For
End If
Next
If matches Then
Exit For
End If
End If
Next
If matches Then
FindElement = i
Else
FindElement = -1
End If
End Function
PowerShell
Add-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST' -filter "system.applicationHost/sites/site[@name='ContosoSite']/logFile/customFields" -name "." -value @{logFieldName='ContosoField';sourceName='ContosoSource';sourceType='ServerVariable'}