I've done a few logging programs. I would typically have a function call to write a dataset to the card. At the beginning of that function I would check a flag (controlled by somewhere else in the code, usually watching a pin state) to see if I wanted to log a data line. If the flag isn't set, return immediately. Then (or concurrently with the previous check) I would check the "if the file was actually able to be opened" flag (that I tested back in
startup()). If that flag isn't set, return immediately. Then open the file for writing, write out my dataset, then close the file. Finally, return from the function.
That way, if power is interrupted between write attempts (when I'm collecting and manipulating data), I don't corrupt the SD card, and nothing is cached in a write buffer. This is particularly important if you are only writing to the SD card at 1 dataset per second or less often. Also, if I flip the switch (or send the command) while a dataset is being written, the dataset finishes writing and the file is closed before I update the flag, so I don't have to worry about a partial dataset in my file.
Also, when I'm checking to see if I want to continue logging (either by looking at a pin state or by command from one of many I/O streams) I only have to set or clear a flag, I don't have to remember to open/close a file at that point, and any future (in operation) commands to write to a file aren't trying to write to a closed file potentially causing errors. File operations for writing datasets is contained to one small section of my code instead of being scattered throughout.