Google OR-Tools v9.15
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
message_callback.py
Go to the documentation of this file.
1#!/usr/bin/env python3
2# Copyright 2010-2025 Google LLC
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15"""Definition and tools for message callbacks.
16
17Message callbacks are used to get the text messages emitted by solvers during
18the solve.
19
20 Typical usage example:
21
22 # Print messages to stdout.
23 result = solve.solve(
24 model, parameters.SolverType.GSCIP,
25 msg_cb=message_callback.printer_message_callback(prefix='[solver] '))
26
27 # Log messages with absl.logging.
28 result = solve.solve(
29 model, parameters.SolverType.GSCIP,
30 msg_cb=lambda msgs: message_callback.log_messages(
31 msgs, prefix='[solver] '))
32"""
33
34import sys
35import threading
36from typing import Callable, List, Sequence, TextIO
37
38from absl import logging
39
40SolveMessageCallback = Callable[[Sequence[str]], None]
41
42
44 *, file: TextIO = sys.stdout, prefix: str = ""
45) -> SolveMessageCallback:
46 """Returns a message callback that prints to a file.
47
48 It prints its output to the given text file, prefixing each line with the
49 given prefix.
50
51 For each call to the returned message callback, the output_stream is flushed.
52
53 Args:
54 file: The file to print to. It prints to stdout by default.
55 prefix: The prefix to print in front of each line.
56
57 Returns:
58 A function matching the expected signature for message callbacks.
59 """
60 mutex = threading.Lock()
61
62 def callback(messages: Sequence[str]) -> None:
63 with mutex:
64 for message in messages:
65 file.write(prefix)
66 file.write(message)
67 file.write("\n")
68 file.flush()
69
70 return callback
71
72
74 messages: Sequence[str], *, level: int = logging.INFO, prefix: str = ""
75) -> None:
76 """Logs the input messages from a message callback using absl.logging.log().
77
78 It logs each line with the given prefix. It setups absl.logging so that the
79 logs use the file name and line of the caller of this function.
80
81 Typical usage example:
82
83 result = solve.solve(
84 model, parameters.SolverType.GSCIP,
85 msg_cb=lambda msgs: message_callback.log_messages(
86 msgs, prefix='[solver] '))
87
88 Args:
89 messages: The messages received in the message callback (typically a lambda
90 function in the caller code).
91 level: One of absl.logging.(DEBUG|INFO|WARNING|ERROR|FATAL).
92 prefix: The prefix to print in front of each line.
93 """
94 for message in messages:
95 logging.log(level, "%s%s", prefix, message)
96
97
98logging.ABSLLogger.register_frame_to_skip(__file__, log_messages.__name__)
99
100
101def vlog_messages(messages: Sequence[str], level: int, *, prefix: str = "") -> None:
102 """Logs the input messages from a message callback using absl.logging.vlog().
103
104 It logs each line with the given prefix. It setups absl.logging so that the
105 logs use the file name and line of the caller of this function.
106
107 Typical usage example:
108
109 result = solve.solve(
110 model, parameters.SolverType.GSCIP,
111 msg_cb=lambda msgs: message_callback.vlog_messages(
112 msgs, 1, prefix='[solver] '))
113
114 Args:
115 messages: The messages received in the message callback (typically a lambda
116 function in the caller code).
117 level: The verbose log level, e.g. 1, 2...
118 prefix: The prefix to print in front of each line.
119 """
120 for message in messages:
121 logging.vlog(level, "%s%s", prefix, message)
122
123
124logging.ABSLLogger.register_frame_to_skip(__file__, vlog_messages.__name__)
125
126
127def list_message_callback(sink: List[str]) -> SolveMessageCallback:
128 """Returns a message callback that logs messages to a list.
129
130 Args:
131 sink: The list to append messages to.
132
133 Returns:
134 A function matching the expected signature for message callbacks.
135 """
136 mutex = threading.Lock()
137
138 def callback(messages: Sequence[str]) -> None:
139 with mutex:
140 for message in messages:
141 sink.append(message)
142
143 return callback
SolveMessageCallback list_message_callback(List[str] sink)
None vlog_messages(Sequence[str] messages, int level, *, str prefix="")
None log_messages(Sequence[str] messages, *, int level=logging.INFO, str prefix="")
SolveMessageCallback printer_message_callback(*, TextIO file=sys.stdout, str prefix="")