# Cannot capture log with JuMP

**URL:** <https://discourse.julialang.org/t/cannot-capture-log-with-jump/55365>\
**Category:** Optimization (Mathematical)\
**Tags:** jump, cplex\
**Created:** [February 16, 2021, 1:19am UTC](https://discourse.julialang.org/t/cannot-capture-log-with-jump/55365 "2021-02-16T01:19:20Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [February 16, 2021, 1:19am UTC](https://discourse.julialang.org/t/cannot-capture-log-with-jump/55365/1 "2021-02-16T01:19:20Z")

</div>

I wanna capture CPLEX log in a file when it executes. However, when solving MIP instances the last bit of the log is never captured by `redirect_stdout` and `redirect_stderr`. I do not know the reason, I only know it happens every single time. So I decided to do an workaround, and use `CPLEX.CPXsetlogfilename` to set a filename where the log will be saved. But the problem is, I am reading the instances from an MPS, so I do not have `direct_model` available (please correct me if I am wrong, but it seems like `read_from_file` does not allow you to get a `DIRECT` mode model). So I need to get a `Model` with a `CachingOptimizer` and do:

```julia
model = JuMP.read_from_file(filepath) 
JuMP.set_optimizer(model, optimizer) 
for (name, value) in optimizer_conf 
    JuMP.set_optimizer_attribute(model, name, value) 
end 
relax && JuMP.relax_integrality(model) 
if optimizer === CPLEX.Optimizer 
    CPX_model = MOI.get(model, MOI.RawSolver()) 
    CPLEX.CPXsetlogfilename( 
      CPX_model.env, "./temporary_CPLEX_log.txt", "w+" 
    )   
end
...

```

But then I am greeted with the following error message:

```julia
ERROR: LoadError: JuMP.OptimizeNotCalled()
Stacktrace:
 [1] _moi_get_result(::MathOptInterface.Utilities.CachingOptimizer{MathOptInterface.AbstractOptimizer,MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}, ::MathOptInterface.RawSolver) at /home/henrique/.julia/packages/JuMP/y5vgk/src/JuMP.jl:944
 [2] get(::JuMP.Model, ::MathOptInterface.RawSolver) at /home/henrique/.julia/packages/JuMP/y5vgk/src/JuMP.jl:959
 [3] read_and_solve_file(::String, ::Type{T} where T, ::Array{Pair{String,Any},1}, ::IOStream; relax::Bool, close_delay::Float64) at /home/henrique/Aulas/doutorado/phd/scripts/read_and_solve_mps/script.jl:54
 [4] read_and_solve_file at /home/henrique/Aulas/doutorado/phd/scripts/read_and_solve_mps/script.jl:46 [inlined]

```

where the offending line is:

```julia
CPX_model = MOI.get(model, MOI.RawSolver()) 

```

So I cannot get the `RawSolver` (that I need to set the log filename) until I call `optimize!` but after calling `optimize!` the log was already written in `stdout` and it is too late to set the log filename.

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [February 16, 2021, 1:22am UTC](https://discourse.julialang.org/t/cannot-capture-log-with-jump/55365/2 "2021-02-16T01:22:29Z")

</div>

Use something like

```julia
function optimizer()
    model = CPLEX.Optimizer()
    CPXsetlogfilename(model.env, "./temporary_CPLEX_log.txt", "w+")
    return model
end

model = read_from_file(filepath)
set_optimizer(model, optimizer)

```

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [February 16, 2021, 1:31am UTC](https://discourse.julialang.org/t/cannot-capture-log-with-jump/55365/3 "2021-02-16T01:31:22Z")

</div>

Thank your very much @odow, I will try that.

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [February 16, 2021, 2:58am UTC](https://discourse.julialang.org/t/cannot-capture-log-with-jump/55365/4 "2021-02-16T02:58:43Z")

</div>

Unfortunately, the problem seem to come from CPLEX, because even in the logfile this last part of the log is not written but instead blurted in the terminal.

If someone is interested, my code with workaround is [here](https://github.com/henriquebecker91/phd/blob/64d26e25100b85b600533800a389b821ca161878/scripts/read_and_solve_mps/script.jl).

---

<div class="post-metadata">

**Author:** ![miles.lubin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/miles.lubin/32/279_2.png) [@miles.lubin](https://discourse.julialang.org/u/miles.lubin)\
**Post date:** [February 16, 2021, 3:21am UTC](https://discourse.julialang.org/t/cannot-capture-log-with-jump/55365/5 "2021-02-16T03:21:58Z")

</div>

Did you try `Base.Libc.flush_cstdio()` before exiting `redirect_stdout`?

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [February 16, 2021, 2:43pm UTC](https://discourse.julialang.org/t/cannot-capture-log-with-jump/55365/6 "2021-02-16T14:43:48Z")

</div>

Thank you very much. This seem to have fixed my problem (and this was a problem that bothered many times in the past). I tried using `Base.flush` in the past but now it seems clear why it did not work. Seems like CPLEX code does not call the `C` version of `flush` in their code before finishing, and the text is lost in a limbo, while Gurobi always flushes before returning.
