Here's what I have been using.  

Any improvements / comments are welcome.


    (* this opens a notebook file and if notebook exists it CLEARS the contents as well  *)
    OpenNB[fname_] := Module[{dir, fns, nb},
       dir = NotebookDirectory[];
       fns = FileNames[FileNameJoin[{dir, fname}]];
       If[fns === {}, (
         nb = CreateNotebook[];
         NotebookSave[nb, FileNameJoin[{dir, fname}]];
         ), (
         nb = NotebookOpen[fns[[1]]];
         SelectionMove[nb, All, Notebook];
         NotebookDelete[nb];
         )
        ];
       Return[nb];
       ];
    
    (* this works for a sequence of arguments, like Print[] *)
    PrintNB[nb_, args__] := Module[{boxes}, (
        If[nb === null, (
           Print[args];
           ), (
           boxes = ToBoxes /@ List[args];
           NotebookWrite[nb, Cell[BoxData[  RowBox[boxes]], "Output"]];
           )
          ];
        )
       ];
    
    PrintNBPageBreak[nb_] := Module[{}, (
        NotebookWrite[nb, Cell["", "PageBreak"]];
        )
       ];
    PrintHeader[nb_, str_] := PrintNB[nb, Style[str, Black, Bold, Larger]];
    PrintSubHeader[nb_, str_] := PrintNB[nb, Style[str, Black, Bold]];

**Here is example usage**

    logNB = OpenNB["ouputlog.nb"];
    PrintNB[logNB, "Execution Log for: ", NotebookFileName[]];
    PrintNB[logNB, "Started at: ", DateString[]];

    f[r] = r^\[Gamma]*Exp[-\[Kappa] r];
    PrintNB[logNB, "f(r) = ", f[r]]; 


**Here is the output**

[![enter image description here][1]][1]

Note that is you use null for the notebook argument, the output will be printed to the current executing notebook (just like Print[]).


  [1]: https://i.sstatic.net/vdPNp.png