• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

devonfw / IDEasy / 22317391561

23 Feb 2026 05:30PM UTC coverage: 70.257% (-0.2%) from 70.474%
22317391561

Pull #1714

github

web-flow
Merge 5be048514 into 379acdc9d
Pull Request #1714: #404: #1713: advanced logging

4066 of 6384 branches covered (63.69%)

Branch coverage included in aggregate %.

10598 of 14488 relevant lines covered (73.15%)

3.08 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

79.41
cli/src/main/java/com/devonfw/tools/ide/log/IdeLogLevel.java
1
package com.devonfw.tools.ide.log;
2

3
import org.slf4j.Logger;
4
import org.slf4j.Marker;
5
import org.slf4j.MarkerFactory;
6
import org.slf4j.event.Level;
7
import org.slf4j.spi.LoggingEventBuilder;
8

9
import com.devonfw.tools.ide.context.IdeStartContextImpl;
10

11
/**
12
 * {@link Enum} with the available log-levels for IDEasy.
13
 *
14
 * @see Slf4jLoggerAdapter
15
 */
16
public enum IdeLogLevel {
3✔
17

18
  /** {@link IdeLogLevel} for tracing (very detailed and verbose logging). */
19
  TRACE("\033[38;5;240m", Level.TRACE, null, JulLogLevel.TRACE),
10✔
20

21
  /** {@link IdeLogLevel} for debugging (more detailed logging). */
22
  DEBUG("\033[90m", Level.DEBUG, null, JulLogLevel.DEBUG),
10✔
23

24
  /** {@link IdeLogLevel} for general information (regular logging). */
25
  INFO(null, Level.INFO, null, JulLogLevel.INFO),
10✔
26

27
  /**
28
   * {@link IdeLogLevel} for a step (logs the step name and groups the following log statements until the next step).
29
   */
30
  STEP("\033[35m", Level.INFO, MarkerFactory.getMarker("STEP"), JulLogLevel.STEP),
11✔
31

32
  /** {@link IdeLogLevel} for user interaction (e.g. questions or options). */
33
  INTERACTION("\033[96m", Level.INFO, MarkerFactory.getMarker("INTERACTION"), JulLogLevel.INTERACTION),
11✔
34

35
  /** {@link IdeLogLevel} for success (an important aspect has been completed successfully). */
36
  SUCCESS("\033[92m", Level.INFO, MarkerFactory.getMarker("SUCCESS"), JulLogLevel.SUCCESS),
11✔
37

38
  /** {@link IdeLogLevel} for a warning (something unexpected or abnormal happened but can be compensated). */
39
  WARNING("\033[93m", Level.WARN, null, JulLogLevel.WARNING),
10✔
40

41
  /**
42
   * {@link IdeLogLevel} for an error (something failed and we cannot proceed or the user has to continue with extreme care).
43
   */
44
  ERROR("\033[91m", Level.ERROR, null, JulLogLevel.ERROR),
10✔
45

46
  /** {@link IdeLogLevel} for {@link com.devonfw.tools.ide.commandlet.Commandlet#isProcessableOutput() processable output} */
47
  PROCESSABLE(null, Level.INFO, MarkerFactory.getMarker("PROCESSABLE"), JulLogLevel.PROCESSABLE);
11✔
48

49
  private final String color;
50

51
  private final Level slf4jLevel;
52

53
  private final Marker slf4jMarker;
54

55
  private final java.util.logging.Level julLevel;
56

57
  /**
58
   * The constructor.
59
   */
60
  private IdeLogLevel(String color, Level slf4jLevel, Marker slf4jMarker, java.util.logging.Level julLevel) {
4✔
61

62
    this.color = color;
3✔
63
    this.slf4jLevel = slf4jLevel;
3✔
64
    this.slf4jMarker = slf4jMarker;
3✔
65
    this.julLevel = julLevel;
3✔
66
  }
1✔
67

68
  /**
69
   * @return the prefix to append for colored output to set color according to this {@link IdeLogLevel}.
70
   */
71
  public String getStartColor() {
72

73
    return this.color;
3✔
74
  }
75

76
  /**
77
   * @return the suffix to append for colored output to reset to default color.
78
   */
79
  public String getEndColor() {
80

81
    return "\033[0m"; // reset color
2✔
82
  }
83

84
  /**
85
   * @return the Slf4J {@link Level}.
86
   */
87
  public Level getSlf4jLevel() {
88

89
    return this.slf4jLevel;
3✔
90
  }
91

92
  /**
93
   * @return the SLF4J {@link Marker}. Will be {@code null} for standard log-levels.
94
   */
95
  public Marker getSlf4jMarker() {
96

97
    return this.slf4jMarker;
×
98
  }
99

100
  /**
101
   * @return the JUL {@link java.util.logging.Level}.
102
   */
103
  public java.util.logging.Level getJulLevel() {
104

105
    return this.julLevel;
3✔
106
  }
107

108
  /**
109
   * @return {@code true} in case of a custom log-level, {@code false} otherwise (standard log-level supported by SLF4J and all reasonable loggers).
110
   */
111
  public boolean isCustom() {
112

113
    return (this.slf4jMarker != null);
×
114
  }
115

116
  /**
117
   * @param logger the SLF4J {@link Logger}.
118
   * @param error the {@link Throwable} with the error to log. Must not be {@code null}.
119
   */
120
  public void log(Logger logger, Throwable error) {
121

122
    log(logger, error, null, (Object[]) null);
×
123
  }
×
124

125
  /**
126
   * @param logger the SLF4J {@link Logger}.
127
   * @param error the optional {@link Throwable} with the error to log or {@code null} for no error.
128
   * @param message the message (template) to log.
129
   */
130
  public void log(Logger logger, Throwable error, String message) {
131

132
    log(logger, error, message, (Object[]) null);
×
133
  }
×
134

135
  /**
136
   * @param logger the SLF4J {@link Logger}.
137
   * @param message the message (template) to log.
138
   */
139
  public void log(Logger logger, String message) {
140

141
    log(logger, null, message, (Object[]) null);
7✔
142
  }
1✔
143

144
  /**
145
   * @param logger the SLF4J {@link Logger}.
146
   * @param message the message (template) to log.
147
   * @param args the optional arguments to fill into the {@code message}. May be {@code null} or empty for no parameters.
148
   */
149
  public void log(Logger logger, String message, Object... args) {
150

151
    log(logger, null, message, args);
6✔
152
  }
1✔
153

154
  /**
155
   * @param logger the SLF4J {@link Logger}.
156
   * @param error the optional {@link Throwable} with the error to log or {@code null} for no error.
157
   * @param message the message (template) to log.
158
   * @param args the optional arguments to fill into the {@code message}. May be {@code null} or empty for no parameters.
159
   */
160
  public void log(Logger logger, Throwable error, String message, Object... args) {
161

162
    LoggingEventBuilder builder = logger.atLevel(this.slf4jLevel).setCause(error);
7✔
163
    if (this.slf4jMarker != null) {
3✔
164
      builder = builder.addMarker(this.slf4jMarker);
5✔
165
    }
166
    if (!Slf4jLoggerAdapter.isEmpty(args)) {
3✔
167
      builder.log(message, args);
5✔
168
    } else if (message == null) {
2!
169
      String msg = error.getMessage();
×
170
      if (msg == null) {
×
171
        msg = error.toString();
×
172
      }
173
      builder.log(msg);
×
174
    } else {
×
175
      builder.log(message);
3✔
176
    }
177
  }
1✔
178

179
  /**
180
   * @return {@code true} if this {@link IdeLogLevel} is enabled (globally), {@code false} otherwise.
181
   */
182
  public boolean isEnabled() {
183

184
    IdeLogLevel threshold = getLogLevel();
2✔
185
    return ordinal() >= threshold.ordinal();
9✔
186
  }
187

188
  static IdeLogLevel getLogLevel() {
189
    IdeLogLevel threshold = IdeLogLevel.TRACE;
2✔
190
    IdeStartContextImpl startContext = IdeStartContextImpl.get();
2✔
191
    if (startContext != null) {
2!
192
      threshold = startContext.getLogLevelLogger();
3✔
193
    }
194
    return threshold;
2✔
195
  }
196

197
  /**
198
   * @param marker the {@link Marker}.
199
   * @return the corresponding {@link IdeLogLevel}.
200
   */
201
  public static IdeLogLevel getLevel(Marker marker) {
202

203
    if (marker == INTERACTION.slf4jMarker) {
4✔
204
      return IdeLogLevel.INTERACTION;
2✔
205
    } else if (marker == STEP.slf4jMarker) {
4✔
206
      return IdeLogLevel.STEP;
2✔
207
    } else if (marker == SUCCESS.slf4jMarker) {
4✔
208
      return IdeLogLevel.SUCCESS;
2✔
209
    } else if (marker == PROCESSABLE.slf4jMarker) {
4✔
210
      return IdeLogLevel.PROCESSABLE;
2✔
211
    } else {
212
      return IdeLogLevel.INFO; // unknown marker
2✔
213
    }
214
  }
215

216
  /**
217
   * @param level the SLF4J log {@link Level}.
218
   * @param marker the SLF4J {@link Marker}.
219
   * @return the {@link IdeLogLevel}.
220
   */
221
  public static IdeLogLevel of(Level level, Marker marker) {
222

223
    return switch (level) {
6!
224
      case ERROR -> IdeLogLevel.ERROR;
2✔
225
      case WARN -> IdeLogLevel.WARNING;
2✔
226
      case INFO -> getLevel(marker);
3✔
227
      case DEBUG -> IdeLogLevel.DEBUG;
2✔
228
      case TRACE -> IdeLogLevel.TRACE;
2✔
229
      default -> throw new IllegalStateException("" + level);
×
230
    };
231
  }
232

233
  /**
234
   * @param level the JUL {@link Level}.
235
   * @return the {@link IdeLogLevel}.
236
   */
237
  public static IdeLogLevel of(java.util.logging.Level level) {
238

239
    for (IdeLogLevel ideLevel : values()) {
16!
240
      if (ideLevel.julLevel == level) {
4✔
241
        return ideLevel;
2✔
242
      }
243
    }
244
    throw new IllegalStateException("" + level);
×
245
  }
246

247
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc