---
title: Initialize local log file sink
summary: Open an append-mode CSV writer for audit, error, or trace logging in non-web hosts.
status: draft
owner: SAIF Documentation
last_reviewed: 2026-07-30
library: SAIF.Framework.Logging
reference_type: package
operation_id: LOG-OP-005
trigger: Caller invokes ToFile() or ToFile(fileName)
---

# Initialize local log file sink

This operation redirects one of the main logging classes away from its default SOAP sink and onto a local CSV file. It is only valid for non-web callers, and it writes the corresponding CSV header exactly once, the first time a sink is opened for that class.

| Field | Value |
| --- | --- |
| **Operation ID** | LOG-OP-005 |
| **Trigger** | Caller invokes `ToFile()` or `ToFile(fileName)` on `clsLogAudit`, `clsLogError`, or `clsLogTrace`. |
| **Inputs** | Optional file name; otherwise the class derives a default path from `clsLogCommon.GetToFileName(...)`. |
| **Outputs** | Opened append-mode `StreamWriter` stored in the class-level `m_OutFile` field. |
| **Primary components** | `clsLogAudit.ToFile`, `clsLogError.ToFile`, `clsLogTrace.ToFile`, `clsLogCommon.GetToFileName` |
| **Entry point** | `SAIF.Framework.Logging/clsLogAudit.vb`, `SAIF.Framework.Logging/clsLogError.vb`, `SAIF.Framework.Logging/clsLogTrace.vb` |

## Steps

1. Check `clsLogCommon.IsWeb` first; if it is `True`, throw `ApplicationException("Logging to files not valid for web applications.")` and stop before opening anything ([BR-003](../business-rules.md#br-003-file-based-logging-is-prohibited-in-web-applications)).
2. For the parameterless overload, derive a default file path through `clsLogCommon.GetToFileName(...)`.
   - Use `IO.Path.GetTempPath()` as the directory root.
   - Combine the current executable name with the requested log type (`AUDIT`, `ERROR`, or `TRACE`).
   - Include the current month and year in the generated file name.
3. In the named overload, create `New IO.StreamWriter(inFileName, True)` only when the class's `m_OutFile` field is still `Nothing`.
4. Write the matching header line exactly once (`AuditInfoStruct.CSVHeader`, `ErrorInfoStruct.CSVHeader`, or `TraceInfoStruct.CSVHeader`) and flush the writer.
5. Leave an already-open writer untouched on any subsequent `ToFile(...)` call for the same logging class.

## Process flow

The following diagram visualizes this operation's control flow.

```mermaid
flowchart TD
	Start([ToFile request]) --> Web{IsWeb?}
	Web -->|Yes| EndErr([Throw ApplicationException])
	Web -->|No| Named{Explicit file name?}
	Named -->|No| BuildName[Build default file name]
	Named -->|Yes| CheckWriter{Writer already open?}
	BuildName --> CheckWriter
	CheckWriter -->|Yes| EndReuse([Reuse existing writer])
	CheckWriter -->|No| Open[Open StreamWriter append mode]
	Open --> Header[Write CSV header and flush]
	Header --> EndOk([Writer ready])
```

## Failure and edge-case behavior

- Web callers are rejected immediately with a thrown exception instead of being silently redirected to the SOAP sink ([BR-003](../business-rules.md#br-003-file-based-logging-is-prohibited-in-web-applications)).
- Repeated `ToFile(...)` calls do not reopen the stream or re-write the header once `m_OutFile` has already been set for that class.
- `clsLogTrace.ToFile(...)` remains callable even though trace output is otherwise obsolete; it only prepares the writer and never receives any trace data to write.

## Related documentation
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)
- [Configuration](../configuration.md)

## Sources
- `SAIF.Framework.Logging/clsLogAudit.vb`
- `SAIF.Framework.Logging/clsLogError.vb`
- `SAIF.Framework.Logging/clsLogTrace.vb`
- `SAIF.Framework.Logging/clsLogCommon.vb`
- `SAIF.Framework.Logging/AuditInfoStruct.vb`
- `SAIF.Framework.Logging/ErrorInfoStruct.vb`
- `SAIF.Framework.Logging/TraceInfoStruct.vb`
