class_docstr: Experiment writer for CSVLogger.
  
  Args:
      log_dir: Directory for the experiment logs
docstr: Save recorded metrics into files.
docstr_tok: ["Save","recorded","metrics","into","files","."]
code: def save(self) -> None:
      """Save recorded metrics into files."""
      if not self.metrics:
          return
  
      new_keys = self._record_new_keys()
      file_exists = self._fs.isfile(self.metrics_file_path)
  
      if new_keys and file_exists:
          # we need to re-write the file if the keys (header) change
          self._rewrite_with_new_header(self.metrics_keys)
  
      with self._fs.open(
          self.metrics_file_path,
          mode=("a" if file_exists else "w"),
          newline="",
      ) as file:
          writer = csv.DictWriter(file, fieldnames=self.metrics_keys)
          if not file_exists:
              # only write the header if we're writing a fresh file
              writer.writeheader()
          writer.writerows(self.metrics)
  
      self.metrics = []
  
imports: import csv
  import logging
  import os
  from argparse import Namespace
  from typing import Any, Dict, List, Optional, Set, Union
  from torch import Tensor
  from typing_extensions import override
  from lightning.fabric.loggers.logger import Logger, rank_zero_experiment
  from lightning.fabric.utilities.cloud_io import _is_dir, get_filesystem
  from lightning.fabric.utilities.logger import _add_prefix
  from lightning.fabric.utilities.rank_zero import rank_zero_only, rank_zero_warn
  from lightning.fabric.utilities.types import _PATH
label_desc: Use image node_id 3 for calling the _ExperimentWriter obj's underlying member method code with example usage: obj.save() without return types