func (log *fileSagaLog) GetMessages(sagaId string) ([]saga.SagaMessage, error) {
	fileName := log.getSagaLogFileName(sagaId)
	if _, err := os.Stat(fileName); err != nil {
		return nil, nil
	}
	logFile, err := os.Open(fileName)
	if err != nil {
		return nil, err
	}
	defer logFile.Close()
	msgs := make([]saga.SagaMessage, 0)
	scanner := bufio.NewScanner(logFile)
	nextToken := scanner.Scan()
	for nextToken == true {
		msg, err := parseMessage(sagaId, scanner)
		if err != nil {
			return nil, err
		}
		msgs = append(msgs, msg)
		nextToken = scanner.Scan()
	}
	return msgs, nil
}
Returns all of the messages logged so far for the
specified saga.
package sagalogs
import (
	"bufio"
	"errors"
	"fmt"
	"io/ioutil"
	"os"
	"path"
	"time"
	"github.com/twitter/scoot/saga"
)
type fileSagaLog struct {
	dirName string
}
func MakeFileSagaLog(dirName string) (*fileSagaLog, error) {
	if err := os.MkdirAll(dirName, os.ModePerm); err != nil {
		return nil, err
	}
	return &fileSagaLog{
		dirName: dirName,
	}, nil
}
func (log *fileSagaLog) getSagaDirectory(sagaId string) string {
	return path.Join(log.dirName, sagaId)
}
func (log *fileSagaLog) getSagaLogFileName(sagaId string) string {
	return path.Join(log.getSagaDirectory(sagaId), "log")
}
func (log *fileSagaLog) createTaskDataFileName(
	sagaId string,
	taskId string,
	msgType saga.SagaMessageType) string {
	fileName := fmt.Sprintf("%v_%v_data_%v",
		msgType.String(),
		taskId,
		time.Now().Format(time.StampMilli),
	)
	return path.Join(log.getSagaDirectory(sagaId), fileName)
}
func (log *fileSagaLog) createJobDataFileName(sagaId string) string {
	fileName := fmt.Sprintf(
		"StartSagaData_%v", time.Now().Format(time.StampNano))
	return path.Join(log.getSagaDirectory(sagaId), fileName)
}
func (log *fileSagaLog) StartSaga(sagaId string, job []byte) error {
	dirName := log.getSagaDirectory(sagaId)
	if _, err := os.Stat(dirName); err != nil {
		if os.IsNotExist(err) {
			err = os.Mkdir(dirName, os.ModePerm)
			if err != nil {
				return err
			}
		} else {
			return err
		}
	}
	dataFileName := log.createJobDataFileName(sagaId)
	err := ioutil.WriteFile(dataFileName, job, os.ModePerm)
	if err != nil {
		return err
	}
	var logFile *os.File
	defer logFile.Close()
	logFileName := log.getSagaLogFileName(sagaId)
	if _, err = os.Stat(logFileName); err != nil {
		if os.IsNotExist(err) {
			logFile, err = os.Create(logFileName)
			if err != nil {
				return err
			}
		} else {
			return err
		}
	} else {
		logFile, err = os.OpenFile(logFileName, os.O_APPEND|os.O_RDWR, os.ModePerm)
		if err != nil {
			return err
		}
	}
	msg := []byte(fmt.Sprintf("%v\n%v\n",
		saga.StartSaga.String(),
		dataFileName))
	_, err = logFile.Write(msg)
	if err != nil {
		return err
	}
	logFile.Sync()
	return nil
}
func (log *fileSagaLog) LogMessage(message saga.SagaMessage) error {
	return log.logMessages([]saga.SagaMessage{message})
}
func (log *fileSagaLog) LogBatchMessages(msgs []saga.SagaMessage) error {
	return log.logMessages(msgs)
}
func (log *fileSagaLog) logMessages(msgs []saga.SagaMessage) error {
	if len(msgs) == 0 {
		return errors.New("Empty messages slice passed to logMessages")
	}
	fileName := log.getSagaLogFileName(msgs[0].SagaId)
	logFile, err := os.OpenFile(fileName, os.O_APPEND|os.O_RDWR, os.ModePerm)
	defer logFile.Close()
	if err != nil {
		return err
	}
	for _, message := range msgs {
		msg := []byte(fmt.Sprintf("%v\n", message.MsgType.String()))
		if message.MsgType == saga.StartTask ||
			message.MsgType == saga.EndTask ||
			message.MsgType == saga.StartCompTask ||
			message.MsgType == saga.EndCompTask {
			dataFileName := log.createTaskDataFileName(
				message.SagaId, message.TaskId, message.MsgType)
			err = ioutil.WriteFile(dataFileName, message.Data, os.ModePerm)
			if err != nil {
				return err
			}
			msg = append(msg, []byte(
				fmt.Sprintf("%v\n%v\n",
					message.TaskId,
					dataFileName))...)
		}
		_, err = logFile.Write(msg)
		if err != nil {
			return err
		}
	}
	logFile.Sync()
	return nil
}