or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

basic-logging.mdindex.mdprogress-bars.mdworkers.md

basic-logging.mddocs/

0

# Basic Progress Logging

1

2

Core logging functionality that provides state management, message logging, and iteration tracking capabilities. The ProgressLogger class serves as the foundation for all other proglog functionality and can be used standalone for simple logging scenarios without progress bars.

3

4

## Capabilities

5

6

### Logger Initialization

7

8

Create a new progress logger with optional initial state.

9

10

```python { .api }

11

class ProgressLogger:

12

def __init__(self, init_state=None):

13

"""

14

Initialize a new progress logger.

15

16

Parameters:

17

- init_state (dict, optional): Dictionary representing the initial state

18

"""

19

```

20

21

**Usage Example:**

22

23

```python

24

from proglog import ProgressLogger

25

26

# Basic logger

27

logger = ProgressLogger()

28

29

# Logger with initial state

30

logger = ProgressLogger(init_state={"task": "processing", "stage": 1})

31

```

32

33

### Message Logging

34

35

Add messages to the logger's log with automatic indentation support for hierarchical logging.

36

37

```python { .api }

38

def log(self, message):

39

"""

40

Add a message to the logs with current indentation.

41

42

Parameters:

43

- message (str): Message to log

44

"""

45

```

46

47

**Usage Example:**

48

49

```python

50

logger = ProgressLogger()

51

logger.log("Starting process")

52

logger.log_indent = 2 # Increase indentation

53

logger.log("Processing files")

54

logger.log("Found 10 files")

55

logger.log_indent = 0 # Reset indentation

56

logger.log("Process complete")

57

```

58

59

### Log Management

60

61

Retrieve or save logged messages to a file.

62

63

```python { .api }

64

def dump_logs(self, filepath=None):

65

"""

66

Write logs to file or return as string.

67

68

Parameters:

69

- filepath (str, optional): Path to write logs to. If None, returns logs as string

70

71

Returns:

72

str: Log messages as string (only when filepath is None)

73

"""

74

```

75

76

**Usage Example:**

77

78

```python

79

logger = ProgressLogger()

80

logger.log("Task started")

81

logger.log("Task completed")

82

83

# Get logs as string

84

log_content = logger.dump_logs()

85

print(log_content)

86

87

# Save logs to file

88

logger.dump_logs("process.log")

89

```

90

91

### State Management

92

93

Update logger state and trigger custom callbacks.

94

95

```python { .api }

96

def __call__(self, **kw):

97

"""

98

Update the logger state and trigger callback.

99

100

Parameters:

101

- **kw: Arbitrary keyword arguments to update state

102

"""

103

104

def callback(self, **kw):

105

"""

106

Execute custom action after state update.

107

108

This default implementation does nothing. Override in subclasses

109

for custom behavior.

110

111

Parameters:

112

- **kw: State elements that were updated

113

"""

114

```

115

116

**Usage Example:**

117

118

```python

119

class CustomLogger(ProgressLogger):

120

def callback(self, **kw):

121

if "progress" in kw:

122

print(f"Progress updated: {kw['progress']}%")

123

124

logger = CustomLogger()

125

logger(progress=25) # Prints: Progress updated: 25%

126

logger(progress=50, task="processing") # Updates multiple state values

127

```

128

129

### Object Storage

130

131

Store large or non-serializable objects with dedicated callbacks.

132

133

```python { .api }

134

def store(self, **kw):

135

"""

136

Store objects in the logger and trigger store_callback.

137

138

Unlike __call__(), this method is intended for large objects

139

that may not be serializable and are used for operations like

140

drawing plots on the fly.

141

142

Parameters:

143

- **kw: Objects to store

144

"""

145

146

def store_callback(self, **kw):

147

"""

148

Execute custom action after store update.

149

150

This default implementation does nothing. Override in subclasses

151

for custom behavior.

152

153

Parameters:

154

- **kw: Store elements that were updated

155

"""

156

```

157

158

**Usage Example:**

159

160

```python

161

import matplotlib.pyplot as plt

162

163

class PlotLogger(ProgressLogger):

164

def store_callback(self, **kw):

165

if "plot" in kw:

166

kw["plot"].savefig(f"plot_{len(self.stored)}.png")

167

168

logger = PlotLogger()

169

fig, ax = plt.subplots()

170

ax.plot([1, 2, 3], [1, 4, 2])

171

logger.store(plot=fig) # Saves plot automatically

172

```

173

174

### Iteration Tracking

175

176

Iterate through data while automatically updating logger state.

177

178

```python { .api }

179

def iter(self, **kw):

180

"""

181

Iterate through a list while updating the state.

182

183

Parameters:

184

- **kw: Single key-value pair where key is state field name

185

and value is iterable to process

186

187

Yields:

188

Items from the iterable while updating logger state

189

"""

190

```

191

192

**Usage Example:**

193

194

```python

195

logger = ProgressLogger()

196

197

# Iterate through usernames, updating state

198

for username in logger.iter(user=["tom", "tim", "lea"]):

199

print(f"Processing user: {username}")

200

print(f"Current state: {logger.state}")

201

# State['user'] is automatically updated at each iteration

202

203

# Iterate through multiple data types

204

for item in logger.iter(data_file=["file1.txt", "file2.txt", "file3.txt"]):

205

print(f"Processing {item}")

206

```

207

208

## State and Storage Properties

209

210

### State Dictionary

211

212

```python { .api }

213

# Instance attributes

214

state: dict # Current logger state

215

stored: dict # Stored objects (large/non-serializable)

216

logs: list # List of log messages

217

log_indent: int # Current indentation level for logs

218

```

219

220

**Direct Access Example:**

221

222

```python

223

logger = ProgressLogger()

224

logger(task="processing", progress=0)

225

226

# Direct state access

227

print(logger.state) # {'task': 'processing', 'progress': 0}

228

229

# Update state directly

230

logger.state["progress"] = 50

231

logger.callback(progress=50) # Manually trigger callback

232

```