# Rotate and remove old Logstash output logs

**URL:** <https://discuss.elastic.co/t/rotate-and-remove-old-logstash-output-logs/256803>\
**Category:** Logstash\
**Created:** [November 26, 2020, 5:20pm UTC](https://discuss.elastic.co/t/rotate-and-remove-old-logstash-output-logs/256803 "2020-11-26T17:20:47Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![denisdM](https://avatars.discourse-cdn.com/v4/letter/d/96bed5/32.png) [@denisdM](https://discuss.elastic.co/u/denisdM)\
**Post date:** [November 26, 2020, 5:20pm UTC](https://discuss.elastic.co/t/rotate-and-remove-old-logstash-output-logs/256803/1 "2020-11-26T17:20:47Z")

</div>

Hello,

I've got a Logstash installation (centos 7.6, Logstash 7.2.0) which work great but produce logs and never delete them.  
I've never changed any default configuration so the `/etc/logstash/log4j2.properties` files contains this :

```auto
status = error
name = LogstashPropertiesConfig

appender.console.type = Console
appender.console.name = plain_console
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = [%d{ISO8601}][%-5p][%-25c] %m%n

appender.json_console.type = Console
appender.json_console.name = json_console
appender.json_console.layout.type = JSONLayout
appender.json_console.layout.compact = true
appender.json_console.layout.eventEol = true

appender.rolling.type = RollingFile
appender.rolling.name = plain_rolling
appender.rolling.fileName = ${sys:ls.logs}/logstash-${sys:ls.log.format}.log
appender.rolling.filePattern = ${sys:ls.logs}/logstash-${sys:ls.log.format}-%d{yyyy-MM-dd}-%i.log.gz
appender.rolling.policies.type = Policies
appender.rolling.policies.time.type = TimeBasedTriggeringPolicy
appender.rolling.policies.time.interval = 1
appender.rolling.policies.time.modulate = true
appender.rolling.layout.type = PatternLayout
appender.rolling.layout.pattern = [%d{ISO8601}][%-5p][%-25c] %-.10000m%n
appender.rolling.policies.size.type = SizeBasedTriggeringPolicy
appender.rolling.policies.size.size = 100MB
appender.rolling.strategy.type = DefaultRolloverStrategy
appender.rolling.strategy.max = 30

appender.json_rolling.type = RollingFile
appender.json_rolling.name = json_rolling
appender.json_rolling.fileName = ${sys:ls.logs}/logstash-${sys:ls.log.format}.log
appender.json_rolling.filePattern = ${sys:ls.logs}/logstash-${sys:ls.log.format}-%d{yyyy-MM-dd}-%i.log.gz
appender.json_rolling.policies.type = Policies
appender.json_rolling.policies.time.type = TimeBasedTriggeringPolicy
appender.json_rolling.policies.time.interval = 1
appender.json_rolling.policies.time.modulate = true
appender.json_rolling.layout.type = JSONLayout
appender.json_rolling.layout.compact = true
appender.json_rolling.layout.eventEol = true
appender.json_rolling.policies.size.type = SizeBasedTriggeringPolicy
appender.json_rolling.policies.size.size = 100MB
appender.json_rolling.strategy.type = DefaultRolloverStrategy
appender.json_rolling.strategy.max = 30

rootLogger.level = ${sys:ls.log.level}
rootLogger.appenderRef.console.ref = ${sys:ls.log.format}_console
rootLogger.appenderRef.rolling.ref = ${sys:ls.log.format}_rolling

# Slowlog

appender.console_slowlog.type = Console
appender.console_slowlog.name = plain_console_slowlog
appender.console_slowlog.layout.type = PatternLayout
appender.console_slowlog.layout.pattern = [%d{ISO8601}][%-5p][%-25c] %m%n

appender.json_console_slowlog.type = Console
appender.json_console_slowlog.name = json_console_slowlog
appender.json_console_slowlog.layout.type = JSONLayout
appender.json_console_slowlog.layout.compact = true
appender.json_console_slowlog.layout.eventEol = true

appender.rolling_slowlog.type = RollingFile
appender.rolling_slowlog.name = plain_rolling_slowlog
appender.rolling_slowlog.fileName = ${sys:ls.logs}/logstash-slowlog-${sys:ls.log.format}.log
appender.rolling_slowlog.filePattern = ${sys:ls.logs}/logstash-slowlog-${sys:ls.log.format}-%d{yyyy-MM-dd}-%i.log.gz
appender.rolling_slowlog.policies.type = Policies
appender.rolling_slowlog.policies.time.type = TimeBasedTriggeringPolicy
appender.rolling_slowlog.policies.time.interval = 1
appender.rolling_slowlog.policies.time.modulate = true
appender.rolling_slowlog.layout.type = PatternLayout
appender.rolling_slowlog.layout.pattern = [%d{ISO8601}][%-5p][%-25c] %.10000m%n
appender.rolling_slowlog.policies.size.type = SizeBasedTriggeringPolicy
appender.rolling_slowlog.policies.size.size = 100MB
appender.rolling_slowlog.strategy.type = DefaultRolloverStrategy
appender.rolling_slowlog.strategy.max = 30

appender.json_rolling_slowlog.type = RollingFile
appender.json_rolling_slowlog.name = json_rolling_slowlog
appender.json_rolling_slowlog.fileName = ${sys:ls.logs}/logstash-slowlog-${sys:ls.log.format}.log
appender.json_rolling_slowlog.filePattern = ${sys:ls.logs}/logstash-slowlog-${sys:ls.log.format}-%d{yyyy-MM-dd}-%i.log.gz
appender.json_rolling_slowlog.policies.type = Policies
appender.json_rolling_slowlog.policies.time.type = TimeBasedTriggeringPolicy
appender.json_rolling_slowlog.policies.time.interval = 1
appender.json_rolling_slowlog.policies.time.modulate = true
appender.json_rolling_slowlog.layout.type = JSONLayout
appender.json_rolling_slowlog.layout.compact = true
appender.json_rolling_slowlog.layout.eventEol = true
appender.json_rolling_slowlog.policies.size.type = SizeBasedTriggeringPolicy
appender.json_rolling_slowlog.policies.size.size = 100MB
appender.json_rolling_slowlog.strategy.type = DefaultRolloverStrategy
appender.json_rolling_slowlog.strategy.max = 30

logger.slowlog.name = slowlog
logger.slowlog.level = trace
logger.slowlog.appenderRef.console_slowlog.ref = ${sys:ls.log.format}_console_slowlog
logger.slowlog.appenderRef.rolling_slowlog.ref = ${sys:ls.log.format}_rolling_slowlog
logger.slowlog.additivity = false

logger.licensereader.name = logstash.licensechecker.licensereader
logger.licensereader.level = error

```

As asked in this configuration, the files in `/var/logs/logstash/` are rotated and compressed each day but they're never deleted. I still have logs from May 2019. (Mainly `logstash-plain` logs. `logstash-slowlog-plain` log is unique and empty).

I believed that the `strategy.max = 30` config line would delete logs files older than 30 days, but I was wrong. ¯\_(ツ)\_/¯

What's the correct configuration to remove old logs ?

I found [this](https://discuss.elastic.co/t/how-do-i-rotate-the-output-log-files-of-logstash/29108) topic talking about a `logrotate.d` configuration, but I think it'll fight with this `log4j2` configuration and I'm not sure of the result.

Thanks and regards,

---

<div class="post-metadata">

**Author:** ![Badger](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/badger/32/25190_2.png) [@Badger](https://discuss.elastic.co/u/Badger)\
**Post date:** [November 26, 2020, 7:10pm UTC](https://discuss.elastic.co/t/rotate-and-remove-old-logstash-output-logs/256803/2 "2020-11-26T19:10:52Z")

</div>

> [@denisdM](#):
>
> I believed that the `strategy.max = 30` config line would delete logs files older than 30 days, but I was wrong. ¯\_(ツ)\_/¯

In a configuration where filePattern contains %i I think strategy.max applies to that, so that you never get more than 30 files per day.

I tried this, but it had no effect. Perhaps you can get it to work by tuning it.

```auto
appender.rolling.strategy.type = DefaultRolloverStrategy
appender.rolling.strategy.delete.type = Delete
appender.rolling.strategy.delete.basePath = ${sys:ls.logs}
appender.rolling.strategy.delete.maxDepth = 1
appender.rolling.strategy.delete.ifLastModified.type = IfLastModified
appender.rolling.strategy.delete.ifLastModified.age = 30d

```

---

<div class="post-metadata">

**Author:** ![denisdM](https://avatars.discourse-cdn.com/v4/letter/d/96bed5/32.png) [@denisdM](https://discuss.elastic.co/u/denisdM)\
**Post date:** [November 27, 2020, 12:33pm UTC](https://discuss.elastic.co/t/rotate-and-remove-old-logstash-output-logs/256803/3 "2020-11-27T12:33:03Z")

</div>

Hello Badger,

Thanks for helping 🙂  
Is there documentation anywhere about the available options ? The `delete` configuration and all `maxDepth`, `lastModified`, and other options... where did you found that possibility ?

Thanks and regards,

---

<div class="post-metadata">

**Author:** ![Badger](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/badger/32/25190_2.png) [@Badger](https://discuss.elastic.co/u/Badger)\
**Post date:** [November 27, 2020, 1:43pm UTC](https://discuss.elastic.co/t/rotate-and-remove-old-logstash-output-logs/256803/4 "2020-11-27T13:43:16Z")

</div>

The options are documented [here](https://logging.apache.org/log4j/2.x/manual/appenders.html#CustomDeleteOnRollover). There is an example [here](https://stackoverflow.com/questions/46360848/very-simple-log4j2-properties-configuration-file-using-console-and-rolling-file).

---

<div class="post-metadata">

**Author:** ![denisdM](https://avatars.discourse-cdn.com/v4/letter/d/96bed5/32.png) [@denisdM](https://discuss.elastic.co/u/denisdM)\
**Post date:** [December 7, 2020, 8:54am UTC](https://discuss.elastic.co/t/rotate-and-remove-old-logstash-output-logs/256803/5 "2020-12-07T08:54:51Z")

</div>

Hello Badger,

Thanks for your help. It was successful !

Here's my final `/etc/logstash/log4j2.properties` file :

```auto
status = error
name = LogstashPropertiesConfig

appender.console.type = Console
appender.console.name = plain_console
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = [%d{ISO8601}][%-5p][%-25c] %m%n

appender.json_console.type = Console
appender.json_console.name = json_console
appender.json_console.layout.type = JSONLayout
appender.json_console.layout.compact = true
appender.json_console.layout.eventEol = true

appender.rolling.type = RollingFile
appender.rolling.name = plain_rolling
appender.rolling.fileName = ${sys:ls.logs}/logstash-${sys:ls.log.format}.log
appender.rolling.filePattern = ${sys:ls.logs}/logstash-${sys:ls.log.format}-%d{yyyy-MM-dd}-%i.log.gz
appender.rolling.policies.type = Policies
appender.rolling.policies.time.type = TimeBasedTriggeringPolicy
appender.rolling.policies.time.interval = 1
appender.rolling.policies.time.modulate = true
appender.rolling.layout.type = PatternLayout
appender.rolling.layout.pattern = [%d{ISO8601}][%-5p][%-25c] %-.10000m%n
appender.rolling.policies.size.type = SizeBasedTriggeringPolicy
appender.rolling.policies.size.size = 100MB
appender.rolling.strategy.type = DefaultRolloverStrategy
appender.rolling.strategy.max = 30
appender.rolling.strategy.delete.type = Delete
appender.rolling.strategy.delete.basePath = ${sys:ls.logs}
appender.rolling.strategy.delete.maxDepth = 1
appender.rolling.strategy.delete.ifLastModified.type = IfLastModified
# Delete files older than 30 days
appender.rolling.strategy.delete.ifLastModified.age = 30d

appender.json_rolling.type = RollingFile
appender.json_rolling.name = json_rolling
appender.json_rolling.fileName = ${sys:ls.logs}/logstash-${sys:ls.log.format}.log
appender.json_rolling.filePattern = ${sys:ls.logs}/logstash-${sys:ls.log.format}-%d{yyyy-MM-dd}-%i.log.gz
appender.json_rolling.policies.type = Policies
appender.json_rolling.policies.time.type = TimeBasedTriggeringPolicy
appender.json_rolling.policies.time.interval = 1
appender.json_rolling.policies.time.modulate = true
appender.json_rolling.layout.type = JSONLayout
appender.json_rolling.layout.compact = true
appender.json_rolling.layout.eventEol = true
appender.json_rolling.policies.size.type = SizeBasedTriggeringPolicy
appender.json_rolling.policies.size.size = 100MB
appender.json_rolling.strategy.type = DefaultRolloverStrategy
appender.json_rolling.strategy.max = 30
appender.json_rolling.strategy.delete.type = Delete
appender.json_rolling.strategy.delete.basePath = ${sys:ls.logs}
appender.json_rolling.strategy.delete.maxDepth = 1
appender.json_rolling.strategy.delete.ifLastModified.type = IfLastModified
# Delete files older than 30 days
appender.json_rolling.strategy.delete.ifLastModified.age = 30d

rootLogger.level = ${sys:ls.log.level}
rootLogger.appenderRef.console.ref = ${sys:ls.log.format}_console
rootLogger.appenderRef.rolling.ref = ${sys:ls.log.format}_rolling

# Slowlog

appender.console_slowlog.type = Console
appender.console_slowlog.name = plain_console_slowlog
appender.console_slowlog.layout.type = PatternLayout
appender.console_slowlog.layout.pattern = [%d{ISO8601}][%-5p][%-25c] %m%n

appender.json_console_slowlog.type = Console
appender.json_console_slowlog.name = json_console_slowlog
appender.json_console_slowlog.layout.type = JSONLayout
appender.json_console_slowlog.layout.compact = true
appender.json_console_slowlog.layout.eventEol = true

appender.rolling_slowlog.type = RollingFile
appender.rolling_slowlog.name = plain_rolling_slowlog
appender.rolling_slowlog.fileName = ${sys:ls.logs}/logstash-slowlog-${sys:ls.log.format}.log
appender.rolling_slowlog.filePattern = ${sys:ls.logs}/logstash-slowlog-${sys:ls.log.format}-%d{yyyy-MM-dd}-%i.log.gz
appender.rolling_slowlog.policies.type = Policies
appender.rolling_slowlog.policies.time.type = TimeBasedTriggeringPolicy
appender.rolling_slowlog.policies.time.interval = 1
appender.rolling_slowlog.policies.time.modulate = true
appender.rolling_slowlog.layout.type = PatternLayout
appender.rolling_slowlog.layout.pattern = [%d{ISO8601}][%-5p][%-25c] %.10000m%n
appender.rolling_slowlog.policies.size.type = SizeBasedTriggeringPolicy
appender.rolling_slowlog.policies.size.size = 100MB
appender.rolling_slowlog.strategy.type = DefaultRolloverStrategy
appender.rolling_slowlog.strategy.max = 30
appender.rolling_slowlog.strategy.delete.type = Delete
appender.rolling_slowlog.strategy.delete.basePath = ${sys:ls.logs}
appender.rolling_slowlog.strategy.delete.maxDepth = 1
appender.rolling_slowlog.strategy.delete.ifLastModified.type = IfLastModified
# Delete files older than 30 days
appender.rolling_slowlog.strategy.delete.ifLastModified.age = 30d

appender.json_rolling_slowlog.type = RollingFile
appender.json_rolling_slowlog.name = json_rolling_slowlog
appender.json_rolling_slowlog.fileName = ${sys:ls.logs}/logstash-slowlog-${sys:ls.log.format}.log
appender.json_rolling_slowlog.filePattern = ${sys:ls.logs}/logstash-slowlog-${sys:ls.log.format}-%d{yyyy-MM-dd}-%i.log.gz
appender.json_rolling_slowlog.policies.type = Policies
appender.json_rolling_slowlog.policies.time.type = TimeBasedTriggeringPolicy
appender.json_rolling_slowlog.policies.time.interval = 1
appender.json_rolling_slowlog.policies.time.modulate = true
appender.json_rolling_slowlog.layout.type = JSONLayout
appender.json_rolling_slowlog.layout.compact = true
appender.json_rolling_slowlog.layout.eventEol = true
appender.json_rolling_slowlog.policies.size.type = SizeBasedTriggeringPolicy
appender.json_rolling_slowlog.policies.size.size = 100MB
appender.json_rolling_slowlog.strategy.type = DefaultRolloverStrategy
appender.json_rolling_slowlog.strategy.max = 30
appender.json_rolling_slowlog.strategy.delete.type = Delete
appender.json_rolling_slowlog.strategy.delete.basePath = ${sys:ls.logs}
appender.json_rolling_slowlog.strategy.delete.maxDepth = 1
appender.json_rolling_slowlog.strategy.delete.ifLastModified.type = IfLastModified
# Delete files older than 30 days
appender.json_rolling_slowlog.strategy.delete.ifLastModified.age = 30d

logger.slowlog.name = slowlog
logger.slowlog.level = trace
logger.slowlog.appenderRef.console_slowlog.ref = ${sys:ls.log.format}_console_slowlog
logger.slowlog.appenderRef.rolling_slowlog.ref = ${sys:ls.log.format}_rolling_slowlog
logger.slowlog.additivity = false

logger.licensereader.name = logstash.licensechecker.licensereader
logger.licensereader.level = error

```

Maybe it could be useful to add theses configuration in the defaults file, don't you think ? I'm not sure anyone want to keep theses files for years 😃

Best regards,

---

<div class="post-metadata">

**Author:** ![Badger](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/badger/32/25190_2.png) [@Badger](https://discuss.elastic.co/u/Badger)\
**Post date:** [December 7, 2020, 8:04pm UTC](https://discuss.elastic.co/t/rotate-and-remove-old-logstash-output-logs/256803/6 "2020-12-07T20:04:17Z")

</div>

> [@denisdM](#):
>
> It was successful !

Good for you 🙂 I just cannot get it to work ☹

---

<div class="post-metadata">

**Author:** ![denisdM](https://avatars.discourse-cdn.com/v4/letter/d/96bed5/32.png) [@denisdM](https://discuss.elastic.co/u/denisdM)\
**Post date:** [December 9, 2020, 8:50am UTC](https://discuss.elastic.co/t/rotate-and-remove-old-logstash-output-logs/256803/7 "2020-12-09T08:50:45Z")

</div>

Did you completely restart the service after the modification ?  
If that works with me... that should work with you... 🤨

---

<div class="post-metadata">

**Author:** ![Badger](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/badger/32/25190_2.png) [@Badger](https://discuss.elastic.co/u/Badger)\
**Post date:** [December 9, 2020, 5:09pm UTC](https://discuss.elastic.co/t/rotate-and-remove-old-logstash-output-logs/256803/8 "2020-12-09T17:09:20Z")

</div>

I know I restarted logstash because I do not run it as a service. If I need to run logstash I boot a cloud server and run it on the command line. It turns out there were two issues.

Firstly, although I had write access to the directory and log files via the group, which allowed me to delete files using rm, I did not own the log files. Once I used your configuration and chown'd the most recent file, all of the old files owned by the logstash user were deleted.

Secondly, I applied the changes to the appender.rolling. stanza in the log4j2.properties from the most recent version of logstash. That does not work. Specifically, to get size based rotation of /var/log/logstash-plain.log at 1 MB you have to set

```
appender.json_rolling.policies.size.size = 1MB

```

Even if you have

```
appender.rolling.policies.size.size = 100MB

```

it is the json\_rolling size.size that is applied to the plain log. That is unexpected, at least to me.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [January 6, 2021, 5:09pm UTC](https://discuss.elastic.co/t/rotate-and-remove-old-logstash-output-logs/256803/9 "2021-01-06T17:09:28Z")

</div>

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.
