Create custom log tables in Microsoft Sentinel
Every data source that connects to Microsoft Sentinel lands its events in a Log Analytics table. Built-in connectors write to well-known tables like SecurityEvent, CommonSecurityLog, and AzureActivity - tables with fixed schemas that the Microsoft Sentinel analytics rules and workbooks already know how to query. But Contoso's proprietary trading risk management system generates security-relevant events in a custom JSON format that doesn't match any built-in table. Without a custom table, those events have nowhere to land.
Identify when a custom table is needed
A custom log table is the right choice when your data source meets any of these conditions:
- The data format doesn't match any existing built-in table schema.
- You want to store data from an application that sends logs via the Logs Ingestion API rather than a standard connector.
- The data is high-volume and noncritical, making it a candidate for the Auxiliary table plan at a lower ingestion cost.
- You need to define a custom schema to make the data queryable in a structured way.
Before creating a custom table, verify there isn't an existing connector that handles your data source—many purpose-built connectors in the Content Hub write to _CL tables with parsers and workbooks already included.
When you do need a custom table, you have two table plan options. The Analytics plan supports full interactive KQL queries with standard retention—use this for security-relevant data that analysts will actively query. The Auxiliary plan offers lower ingestion cost with limited query capability and short retention—use this for high-volume compliance or usage data that you ingest for archival but rarely query directly.
Create and define a custom table schema
To create a custom table in the Microsoft Defender portal:
Navigate to Microsoft Sentinel > Configuration > Tables.
Select + New custom table.
Enter a table name. Microsoft Sentinel automatically appends the
_CLsuffix to custom log tables. For Contoso's trading system, enterTradingSystemEvents- the table appears asTradingSystemEvents_CLin all queries and schema views.Select the table plan: Analytics for a table that analysts query in investigations, or Auxiliary for high-volume, low-query data.
Define the schema by adding columns. For each column, specify a name and data type. Common data types include
stringfor identifiers and messages,datetimefor timestamps,intfor numeric codes, anddynamicfor nested JSON objects. Add at minimum aTimeGeneratedcolumn of typedatetime- this column is required by all Log Analytics tables and drives time-range filtering in queries.For the Contoso trading risk system, the schema includes:
Column name Type Description TimeGenerateddatetime Event timestamp (UTC) TradeIdstring Unique trade identifier RiskScoreint Calculated risk score (0–100) AlertTypestring Risk alert category UserIdstring Trader who initiated the action SourceSystemstring Originating platform identifier Select Create.
Configure a data collection rule for ingestion
Creating the table establishes the schema and target. Sending data to it requires a Data Collection Rule (DCR) and a Data Collection Endpoint (DCE). The DCE provides the network endpoint that applications call, and the DCR defines the transformation and routing from the source data stream to the target table.
To configure ingestion:
In the Azure portal, navigate to Monitor > Data Collection Endpoints and create a new endpoint in the same region as your workspace. Note the Logs Ingestion URI shown on the endpoint's Overview page—your source application uses this URI to POST events.
Navigate to Monitor > Data Collection Rules and select Create. On the Basics tab, enter a rule name and select the same subscription and resource group as your workspace.
On the Data sources tab, select + Add data source. Set the Data source type to Custom logs (JSON format). Under Destination, select your Log Analytics workspace and the
TradingSystemEvents_CLtable.If your source data format differs from the target table schema, add a Transformation using KQL. For example, to rename an incoming field
risk_scoreto the table columnRiskScore:source | extend RiskScore = toint(risk_score) | project-away risk_scoreSelect Review + create, then Create.
To validate ingestion, have your source application send a test event to the DCE's Logs Ingestion URI with the correct authorization header. After one to two minutes, run the following KQL query in the Defender portal to confirm the event arrived:
TradingSystemEvents_CL
| take 10
If the query returns results, the table and ingestion pipeline are working. If no results appear after five minutes, verify that the DCR is correctly associated with the DCE and that the application is sending to the correct URI.